阅读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库操做数组通常都不会影响原有数组。
相关文章
相关标签/搜索