1. 数组降维 二维数组降维成一维数组(引自vue源码)
利用原理: (1) concat
的属性 : 如果concat方法的参数是一个元素,该元素会被直接插入到新数组中;如果参数是一个数组,该数组的各个元素将被插入到新数组中; (2) apply
的优化:Array.prototype.concat.apply
([], children) 等同于 [].concat(demoArr)
1 2 3 4 5 6 7 8 9 10 11 12 let demoArr = [1 ,2 ,3 ,4 ,5 ,[7 ,8 ],[22 ,23 ,43 ]]export function simpleNormalizeChildren (children ) { for (let i = 0 ; i < children.length; i++) { if (Array .isArray(children[i])) { return Array .prototype.concat.apply([], children) } } return children } simpleNormalizeChildren(demoArr)
扩展: 多维数组递归降维(借助了递归
的能力)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 let children = [1 , [2 ,3 ], [4 , [5 , 6 , [7 , 8 ]]], [9 , 10 ]];function simpleNormalizeChildren (children ) { for (let i = 0 ; i < children.length; i++) { if (Array .isArray(children[i])) { children = Array .prototype.concat.apply([], children); for (let j =0 ; j<children.length; j++) { simpleNormalizeChildren(children) } } } return children; } simpleNormalizeChildren(children);
2. 数组去重 (1) ES6 set
方法 (Set 对象允许你存储任何类型的唯一值)
1 2 3 4 5 6 7 function unique (arr ) { return Array .from(new Set (arr)) } var arr = [1 ,1 ,'true' ,'true' ,true ,true ,15 ,15 ,false ,false , undefined ,undefined , null ,null , NaN , NaN ,'NaN' , 0 , 0 , 'a' , 'a' ,{},{}]; console .log(unique(arr))
set方法无法识别重复的{}空对象
(2)双重for循环,splice去重
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function unique (arr ) { for (var i=0 ; i<arr.length; i++){ for (var j=i+1 ; j<arr.length; j++){ if (arr[i]==arr[j]){ arr.splice(j,1 ); j--; } } } return arr;} var arr = [1 ,1 ,'true' ,'true' ,true ,true ,15 ,15 ,false ,false , undefined ,undefined , null ,null , NaN , NaN ,'NaN' , 0 , 0 , 'a' , 'a' ,{},{}]; console .log(unique(arr))
NaN和{}没有去重,两个null直接消失了
(3) indexOf(新建了一个空数组,遍历旧数组,如果空数组里没遇到重复的遍历项,则添加)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function unique (arr ) { if (!Array .isArray(arr)) { console .log('type error!' ) return } var array = []; for (var i = 0 ; i < arr.length; i++) { if (array.indexOf(arr[i]) === -1 ) { array.push(arr[i]) } } return array; } var arr = [1 ,1 ,'true' ,'true' ,true ,true ,15 ,15 ,false ,false , undefined ,undefined , null ,null , NaN , NaN ,'NaN' , 0 , 0 , 'a' , 'a' ,{},{}]; console .log(unique(arr))
NaN、{}没有去重
(4) sort排序后再去重(sort后一样的元素的会在旁边,只需与身边的对比)高性能,推荐👍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function unique (arr ) { var seen; var targetArr = Array .prototype.concat.call(arr).sort() var result = []; for (var i = 0 ; i <targetArr.length; i++) { if (!i || seen !== targetArr[i]) { result.push(targetArr[i]) } seen = targetArr[i] } return result } var arr = [1 ,1 ,'true' ,'true' ,true ,true ,15 ,15 ,false ,false , undefined ,undefined , null ,null , NaN , NaN ,'NaN' , 0 , 0 , 'a' , 'a' ,{},{}]; console .log(unique(arr));
sort方法需要注意看使用场景,特殊类型的时候,sort会有坑。
(5) underScore 思路版 (提供三个参数)这个思路杂糅上面的方法 array
: 必填参数,去重目标数组isSorted
: 表示目标数组是否已经排序过了,true的话,将会采用方法(4)那样的高效对比。false的话,用indexOfiteratee
: 自定义对目标数组的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function unique (array, isSorted, iteratee ) { var res = []; var seen = []; for (var i = 0 , len = array.length; i < len; i++) { var value = array[i]; var computed = iteratee ? iteratee(value, i, array) : value; if (isSorted) { if (!i || seen !== computed) { res.push(value) } seen = computed; } else if (iteratee) { if (seen.indexOf(computed) === -1 ) { seen.push(computed); res.push(value); } } else if (res.indexOf(value) === -1 ) { res.push(value); } } return res; } console .log(unique(array3, false , function (item ) { return typeof item == 'string' ? item.toLowerCase() : item }));
(6) 利用Object的key是唯一的
1 2 3 4 5 6 7 8 function distinct (array ) { var obj = {}; return array.filter(function (item, index, array ) { return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true ) }) }
真是叹为观止,妙!妙在哪?
array.filter
本身就兼职遍历,过滤,返回新数组
于一身,干净利落
Object的key确实是唯一
的,如果重复时候,只能是覆盖value的
filter过滤条件需要的true和false
就由 Obj是否包含这个type+value
为key 来决定, 如果之前没存进obj,可以任意设置一个value,就是三元运算符里的obj[typeof item + item] = true
API补充:
reduce
升序让数组每一项都调用传入函数,可以设置初始值。 四个参数Accumulator
(acc) (累计器)Current Value
(cur) (当前值)Current Index
(idx) (当前索引)Source Array
(src) (源数组)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])`` ` ` `` javascriptvar names = ['Alice' , 'Bob' , 'Tiff' , 'Bruce' , 'Alice' ];var countedNames = names.reduce(function (allNames, name ) { if (name in allNames) { allNames[name]++; } else { allNames[name] = 1 ; } return allNames; }, {});
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var pipe = (function ( ) { return function (value ) { var funcStack = []; var oproxy = new Proxy ({} , { get : function (pipeObject, fnName ) { console .log('fnName is:' + fnName) if (fnName === 'get' ) { return funcStack.reduce(function (val, fn ) { return fn(val); },value); } funcStack.push(window [fnName]); console .log(funcStack) return oproxy; } }); return oproxy; } }()); var double = n => n * 2 ; var pow = n => n * n; var reverseInt = n => n.toString().split("" ).reverse().join("" ) | 0 ; console .log(pipe(3 )['double' ].pow.get);
slice
类数组 => 真数组
1 2 3 4 5 6 function list ( ) { return Array .prototype.slice.call(arguments ); } var list1 = list(1 , 2 , 3 );
Array.from
从一个类似数组或可迭代对象创建一个新的,浅拷贝
的数组实例。
1 Array .from(arrayLike[, mapFn[, thisArg]])
arrayLike
:想要转换成数组的伪数组对象或可迭代对象。比如拥有一个 length 属性和若干索引属性的任意对象和Map、set等。mapFn
可选:如果指定了该参数,新数组中的每个元素会执行该回调函数。thisArg
可选:可选参数,执行回调函数 mapFn 时 this 对象。
1 2 const someNumbers = { '0' : 10 , '1' : 15 , length : 2 };Array .from(someNumbers, value => value * 2 );
1 2 3 4 function sumArguments ( ) { return Array .from(arguments ).reduce((sum, num ) => sum + num); } sumArguments(1 , 2 , 3 );
Array.concat()
不传参数的时候,是一种浅拷贝的行为
Array.filter(function(){})
如名,filter,过滤,该方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。不改变原数组
1 var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
callback
: 用来测试数组元素的函数 return true时 保留元素 否则不保留。index
: 当前处理索引array
: 调用了filter的数组本身
1 2 3 4 5 function isBigEnough (element ) { return element >= 10 ; } var filtered = [12 , 5 , 8 , 130 , 44 ].filter(isBigEnough);
参考 MDN - slice MDN - reduce MDN - typeof MDN - Array.from 掘金 reduce 掘金 Array.from 拉钩博文 冴羽 Array去重 issue 阮一峰 reduce transduce 关于 函数编程