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;
推荐阅读
-
JavaScript实用库:Lodash源码数组函数解析(五)fill、baseFill、findIndex、baseFindIndex、baseIteratee、findLastIndex
-
JavaScript实用库:Lodash源码数组函数解析(四)dropRight、dropWhile、dropRightWhile、baseWhile
-
JavaScript实用库:Lodash源码数组函数解析(六)first、flatten、flattenDeep、flattenDepth、baseFlatten、isFlattenable
-
JavaScript实用库:Lodash源码数组函数解析(八)initial、join、last、nth、baseNth、(isIndex)
-
JavaScript实用库:Lodash源码数组函数解析(十一)without以及很多我没详戏记细过的
-
JavaScript实用库:Lodash源码数组函数解析(二)
-
JavaScript实用库:Lodash源码数组函数解析(九)remove、reverse、slice
-
JavaScript实用库:Lodash源码数组函数解析(七)fromPairs、toPairs、indexOf、baseIndexOf、strictIndexOf