欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-01-03 12:54:58
...

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

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

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

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

  


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

下面我们来看它的例子:
JavaScript实用库:Lodash源码数组函数解析(四)dropRight、dropWhile、dropRightWhile、baseWhile
和上次的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)。

接下来我们看例子

JavaScript实用库:Lodash源码数组函数解析(四)dropRight、dropWhile、dropRightWhile、baseWhile
然后就是我们的源码部分:

/**
 * 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;

上一篇:

下一篇: