閱讀lodash源碼之旅數組方法篇-compact和concat

魯迅說過:只有閱讀過優秀庫源碼的人,才能配的上是真正的勇士。javascript

compact

建立一個新數組,包含原數組中全部的非假值元素。例如false, null,0, 「」, undefined, 和 NaN 都是被認爲是「假值」。html

注意以上的描述並不包括[],{}由於在js中,這個兩個會進行隱式轉換會把這兩個值轉換成爲true。換句話來講該函數並不會去過濾這兩個值。
在這裏插入圖片描述
官方代碼:java

export function compact(array){ let resIndex = 0; const result = [] if(array == null){ // 會把undefined給排除掉 由於 undefined == null 爲true return result } for(const value of array){ if(value){ result[resIndex++] = value } } return result } 

我的理解代碼:數組

export function compact(array){ let resIndex = 0; const result = [] if(array == null){ // 會把undefined給排除掉 由於 undefined == null 爲true return result } result = array.filter(v=>Boolean(v)) return result } 

直接利用filter進行遍歷,利用boolean,來對元素進行真假轉換。函數

concat

建立一個新數組,將array與任何數組 或 值鏈接在一塊兒。工具

var array = [1]; var other = _.concat(array, 2, [3], [[4]]); console.log(other); // => [1, 2, 3, [4]] console.log(array); // => [1] 

相對來講,concat函數所依賴的工具函數就多幾個。spa

  1. arrayPush數組添加方法
  2. copyArray拷貝數組元素
  3. baseFlatten扁平層級數組
export function concat(){ let length = arguments.length; // 獲取參數的個數 if (!length) { return []; } let args = Array(length - 1); // 取除了第一個參數之外的參數的長度 let array = arguments[0]; // 取出數組的第一項 let index = length; while (index--) { args[index - 1] = arguments[index]; } console.log(args); // 把第一個參數也就是目標數組,看成-1項添加爲array // 判斷一個參數是不是數組,不是就把它轉換成爲數組,若是是數組則拷貝一份數組,再使用arrayPush方法,把每項的參數推動數組裏面去。 return arrayPush(Array.isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); } 

copyArray

拷貝數組,此操做不會影響到原有的數組。code

參數 說明
soure 原數組參數
array 結果數組
export function copyArray(source,array){ let index = -1; let length = source.length; array || (array = Array(length)); while(++index < length){ array[index] = source[index] } return array } 

baseFlatten

該方法主要用於扁平數組的操做htm

export function baseFlatten(array, depth, predicate, isStrict, result) { let index = -1; let length = array.length; predicate || (predicate = isFlattenable); // isFlattenable 判斷是不是數組 result || (result = []); while (++index < length) { let value = array[index]; console.log(value); if (depth > 0 && predicate(value)) { // 若是層級大於0而且該項是數組的話 if (depth > 1) { // 若是須要遞歸的層級大於1的狀況則繼續遞歸下去解套 baseFlatten(value, depth - 1, predicate, isStrict, result); } else { // 若是須要遞歸的層級爲1的狀況,則把全部的項添加目標數組 arrayPush(result, value); } } else if (!isStrict) { result[result.length] = value; } } return result; } isFlattenable(value){ return Array.isArray(value) } 

發散思考,該函數只要是經過depth變量,來控制篩選的層級,那麼我但願實現扁平全部的數組,那應該怎麼操做呢?blog

function flattern(arr) { return arr.reduce((cur, next) => cur.concat(Array.isArray(next) ? flattern(next) : next), []); } 

arrayPush

添加元素進入原數組,會改變原數組結構,相似push方法

let index = -1; let length = values.length; let offset = array.length; while (++index < length) { array[index + offset] = values[index]; } return array; 

總結

  1. ++index和index++不一樣之處,++i就是先加後用,i++就是先用後加。前置++下標不會越界,後置++下標越界。
  2. lodash庫操做數組通常都不會影響原有數組。
相關文章
相關標籤/搜索