本章內容主要是: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;