网易前端面试的时候,面试官问我有几种数组合并的方法,当时第一反应就是concat,但是面试官说几种,我寻思着原生js方法好像也只有concat呀,就说不改变原数组的话concat就可以了。当时没多想,回来之后才发现,这个
1,concat
arr = [1,3].concat([3]);
console.log(arr); // [1,2,3] ;
concat 函数总结,可以合并多个数组,不影响原数组(会造成内存浪费),不能处理嵌套数组.
2,基于for循环使用pop和push方法
function for_pushshift(arr1,arr2){
if (arr1.length > arr2.length) {
for (var i=0; i <arr2.length; i++) {
//if( Array.isArray(arr2[i])) {
//for_pushift(arr1,arr2[i]);
//} else{
arr1.push(arr2[i]);
// }
}
arr2 = null ; // 基于内存考虑
} else {
for (var i=0; i <arr1.length; i++) {
arr2.unshift(arr1[i] );
}
arr1 = null ; // 基于内存考虑
}
return arr1;
}
console.log("push方法数组" + for_pushift(arr1 ,arr2) ) ;
3,使用forEach和pop和push方法实现
这个方法原理和2中一样,只是使用了forEach代替了for循环。for循环方法总结,看上去土而且不好维护,只能合并两个数组,也不能处理嵌套数组。
4,使用reduce()和reduceRight()方法
function concat_reduce( arr1 ,arr2){
if(arr1.length > arr2.length){
return arr1.reduce( function(prev,curr){
if (Array.isArray(curr)) {
concat_reduce(curr);
} else{
prev.push(curr);
return prev ; //return 语句不能忘记,要自己返回prev的值,
}
}, arr2);
} else {
return arr2.reduceRight(function(prev ,curr){
prev.unshift(curr);
return prev ;
} ,arr1);
}
}
5,使用apply方法
function concat_apply() {
// return Array.prototype.push.apply(arr1,arr2);
return Array.prototype.concat.apply([], arguments)
}
使用:
var arr2 = [ 'a','b'];
console.log([concat_apply([[1, 2],[3, 4, 5], [6, 7, 8, 9,[11,12,[13]]],10],arr2)].join(":")) ;
输出为 1,2,3,4,5,6,7,8,9,11,12,13,10,'a','b' 。可以看到,apply方法,简洁高效,且能实现多个数组合并,并且能够实现深度嵌套,注意最后还是使用了concat哦,换成push是不可以的。
6,数组嵌套合并
上面是5中基本的合并数组的方法,注意事项和优缺点在注释里都已经写了。上面1-4方法如果含有嵌套数组,都是直接返回的,也就是没有对嵌套数组整合,对嵌套数组的整合我的思路是使用递归,在循环中加一个判断是否为数组,像下面的例子
function for_pushift(arr1,arr2){
if (arr1.length > arr2.length) {
***for (var i=0; i <arr2.length; i++) {
if( Array.isArray(arr2[i])) {
for_pushift(arr1,arr2[i]);
} else{
arr1.push(arr2[i]);
}***
}
arr2 = null ; // 基于内存考虑
return arr1;
} else {
for (var i=0; i <arr1.length; i++) {
***if(Array.isArray(arr1[i])){
for_pushift(arr1[i],arr2);
} else{
arr2.unshift(arr1[i] );
}***
}
arr1 = null ; // 基于内存考虑
return arr2 ;
}
}
主要是增加了*号部分的判断代码, 其他几种方法也可以增加类似的代码,在上面方法4中的判断语句取消屏蔽就可以实现。方法5是不用做任何改变的,本身就可以实现嵌套的合并。
7,多个数组合并
原生的concat方法可以简单实现多个数组合并,比如[1,2,3].concat([4,5,6],[6,7,8);会返回1,2,3,4,5,6,7,8至于其他方法,应该只是一个接口的问题,可以像下面这样实现。
function for_more(){
var oriArr = arguments[0] ? arguments[0] : [];
var otherArr = Array.prototype.slice.call(arguments,1) ;
otherArr.forEach(function(item){
oriArr.push(item);
})
return oriArr;
}
console.log( for_more([1,2],[3,[4,5]],[6,7]) ); // [1,2,[3,[4,5]],[6,7]];
参数处理好了,上面两个问题整合一下就OK了。另外一种思路是写一个整合函数,参数是一个数组,如果数组有嵌套整合为无嵌套的数组。
function flatten(arr) {
return arr.reduce(function(flat, toFlatten) {
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
}, []);
}
console.log(flatten([[1, 2],[3, 4, 5], [6, 7, 8, 9]]) ) ; //输出 1,2,3,4,5,6,7,8,9
在1,2部分函数的基础上再增加一个这样的函数就OK了;不过这样看来总结一下,还是方法5比较好用。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。