JavaScript实用库:Lodash源码数组函数解析(四)dropRight、dropWhile、dropRightWhile、baseWhile

本章内容主要是:dropRight、dropWhile、dropRightWhile、baseWhile

在这里插入图片描述

Lodash是一个非常好用方便的JavaScript的工具库,使得我们对数据处理能够更加得心应手

接下来我要对Lodash的源码进行剖析学习
每天几个小方法,跟着我一起来学lodash吧

  


1、_.dropRight(array, [n=1])
这个方法和昨天的drop是类似的,但是,它是去除array尾部的n个元素。(n默认值为1。)

下面我们来看它的例子:
在这里插入图片描述
和上次的drop的切片是类似的,大家理解一下
接下来看源码:

/**
 * Creates a slice of `array` with `n` elements dropped from the end.
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Array
 * @param {Array} array The array to query.
 * @param {number} [n=1] The number of elements to drop.
 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
 * @returns {Array} Returns the slice of `array`.
 * @example
 *
 * _.dropRight([1, 2, 3]);
 * // => [1, 2]
 *
 * _.dropRight([1, 2, 3], 2);
 * // => [1]
 *
 * _.dropRight([1, 2, 3], 5);
 * // => []
 *
 * _.dropRight([1, 2, 3], 0);
 * // => [1, 2, 3]
 */
function dropRight(array, n, guard) {
  //获取数组的长度
  var length = array == null ? 0 : array.length;
  //长度为0输出空数组
  if (!length) {
    return [];
  }
  //确定n的值
  n = (guard || n === undefined) ? 1 : toInteger(n);
  n = length - n;
  return baseSlice(array, 0, n < 0 ? 0 : n);
}
module.exports = dropRight;

前面的操作也和drop方法一样,获取array数组的长度,然后就是确定n的值,toInteger方法的源码昨天说过了,大家可以去看看JavaScript实用库:Lodash源码数组函数解析(三) drop、toInteger、toFinite,这个方法就是将取整数方法。

drop方法不同的地方是:使用baseSlice方法进行切片时,起始位置与结束位置的不同。
我们的drop方法的起始位置是传入参数n,结束位置是我们的数组array的长度length
而我们的dropRight方法的起始位置是0,也就是从头开始,结束位置是数组array的长度length减去参数n
意思也特别的通俗易懂


2、.dropWhile(array, [predicate=.identity])
根据中文文档介绍:它的作用是创建一个切片数组,去除array中从起点开始到 predicate 返回假值结束部分。predicate 会传入3个参数: (value, index, array)。

接下来我们看例子

在这里插入图片描述
然后就是我们的源码部分:

/**
 * Creates a slice of `array` excluding elements dropped from the beginning.
 * Elements are dropped until `predicate` returns falsey. The predicate is
 * invoked with three arguments: (value, index, array).
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Array
 * @param {Array} array The array to query.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @returns {Array} Returns the slice of `array`.
 * @example
 *
 * var users = [
 *   { 'user': 'barney',  'active': false },
 *   { 'user': 'fred',    'active': false },
 *   { 'user': 'pebbles', 'active': true }
 * ];
 *
 * _.dropWhile(users, function(o) { return !o.active; });
 * // => objects for ['pebbles']
 *
 * // The `_.matches` iteratee shorthand.
 * _.dropWhile(users, { 'user': 'barney', 'active': false });
 * // => objects for ['fred', 'pebbles']
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.dropWhile(users, ['active', false]);
 * // => objects for ['pebbles']
 *
 * // The `_.property` iteratee shorthand.
 * _.dropWhile(users, 'active');
 * // => objects for ['barney', 'fred', 'pebbles']
 */
function dropWhile(array, predicate) {
  return (array && array.length)
    ? baseWhile(array, baseIteratee(predicate, 3), true)
    : [];
}

module.exports = dropWhile;

上面的例子太难看懂了,不够直观,现在我来举个例子:

function less3(a) {
   return a < 3
}
_.dropWhile([1, 2, 5, 7, 4], less4)
// 从左侧开始,开始索引为less3返回值为false时对应的索引,可知5调用less3时返回false,所以返回值为:[5, 7, 4]


//然后我们顺便提一下dropRightWhile
_.dropRightWhile([7, 2, 5, 2, 1], less4)
// 从右侧开始,开始索引为less3返回值为false时对应的索引,可知5调用less3时返回false,所以返回值为:[7, 2, 5]

所以我们可以看到,dropWhile方法是开始索引为false,而dropRightWhile是结束索引为false。

现在我直接将dropRightWhile的源码写出来,让后最后提一下baseWhile方法才可以解释我们的过程


4、.dropRightWhile(array, [predicate=.identity])

根据中文文档解释,它的功能是:创建一个切片数组,去除array中从 predicate 返回假值开始到尾部的部分。predicate 会传入3个参数: (value, index, array)。

这里例子就不展示了,上面有提到过

现在直接上源码;

/**
 * Creates a slice of `array` excluding elements dropped from the end.
 * Elements are dropped until `predicate` returns falsey. The predicate is
 * invoked with three arguments: (value, index, array).
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Array
 * @param {Array} array The array to query.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @returns {Array} Returns the slice of `array`.
 * @example
 *
 * var users = [
 *   { 'user': 'barney',  'active': true },
 *   { 'user': 'fred',    'active': false },
 *   { 'user': 'pebbles', 'active': false }
 * ];
 *
 * _.dropRightWhile(users, function(o) { return !o.active; });
 * // => objects for ['barney']
 *
 * // The `_.matches` iteratee shorthand.
 * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
 * // => objects for ['barney', 'fred']
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.dropRightWhile(users, ['active', false]);
 * // => objects for ['barney']
 *
 * // The `_.property` iteratee shorthand.
 * _.dropRightWhile(users, 'active');
 * // => objects for ['barney', 'fred', 'pebbles']
 */
function dropRightWhile(array, predicate) {
  return (array && array.length)
    ? baseWhile(array, baseIteratee(predicate, 3), true, true)
    : [];
}

module.exports = dropRightWhile;

4、_.baseWhile

我们直接来看源码:

/**
 * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
 * without support for iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to query.
 * @param {Function} predicate The function invoked per iteration.
 * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Array} Returns the slice of `array`.
 */
function baseWhile(array, predicate, isDrop, fromRight) {
  var length = array.length,
      // 判断截取是从左侧开始还是从右侧开始,如果左侧开始index为-1,右侧开始index取length
      index = fromRight ? length : -1;

  // 如果从左侧开始截取,while循环如下:
  /* 
    while((++index < length) && predicate(array[index], index, array)){}
  */
  // index值不停的加1直到predicate(array[index], index, array)返回false时停止增加,或者index > length时停止增加
  // 此时如果isDrop为true,最终执行结果为slice(array, index, length)
  // 此时如果isDrop为false,最终执行结果为slice(array, 0, index)

  // 如果从右侧开始截取,while循环如下:
  /* 
    while((index--) && predicate(array[index], index, array)){}
  */
  // index值不停的减1直到predicate(array[index], index, array)返回false时停止减小,或者index < 0时停止减小
  // 此时如果isDrop为true,最终执行结果为slice(array, 0, index + 1)
  // 此时如果isDrop为false,最终执行结果为slice(array, index+1, length)

  // predicate是个函数,在index变化过程中,它会对index对应的元素执行predicate函数,当predicate返回值为true时继续执行循环,当predicate为false时结束循环
  
  while ((fromRight ? index-- : ++index < length) &&
    predicate(array[index], index, array)) {}

  return isDrop
    ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
    : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
}

module.exports = baseWhile;

所以我们可以根据baseWhile的四个参数确定数组的截取方向以及条件等。


最后的总结:
drop吃从左侧开始截取,开始位置为n,结束位置为数组长度length

dropRight是从右侧开始截取,开始位置为0,结束位置为数组长度length-n

dropWhile是从左侧开始截取,开始位置为数组中元素调用predicate方法时返回值为false时对应的索引,结束位置为数组长度length;

dropRightWhile是从右侧开始截取,开始位置为0,结束位置为数组中元素调用predicate方法时返回值为false时对应的索引加1;

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弓长于水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值