JavaScript数组合并几种方法

网易前端面试的时候,面试官问我有几种数组合并的方法,当时第一反应就是concat,但是面试官说几种,我寻思着原生js方法好像也只有concat呀,就说不改变原数组的话concat就可以了。当时没多想,回来之后才发现,这个小问题其实牵涉了很多问题,比如对于concat不改变原数组就存在内存占用问题;再者如果数组有多重嵌套怎么办? 要合并多组数组怎么办?细思极恐自己面试草率的回答无异于作死。
我分三部分讲数组合并的问题,第一部分,对于简单的两个数组合并的方法;第二部分,对于嵌套数组的实现方法;第三部分,多个数组合并的方法。
  1. 合并数组的几种方法
    /1,concat方法
var arr1 = [1,2,3];
var arr2 = [ 'a','b'];
var arr3 = [ null ,undefined];
var arr = arr1.concat(arr2,arr3);
console.log( arr);   //  [1,2,'a' ,'b' ,null,undefined];
var arr4 = [['c','d'] , 3] ;
arr = arr1.concat(arr4);
console.log(arr);         // [1,2,['c' ,'d'] ,3] ;
/ concat 函数总结,可以合并多个数组,不影响原数组(会造成内存浪费),不能处理嵌套数组

2,用for循环利用push 和unshift 方法实现
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 ; // 基于内存考虑
} 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, 和方法2原理一样,for循环可以用Array.forEach()实现
///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);
    }
}
arr1 = [1,2,3,4] ;arr2 = [5,[6,7,8]] ;
console.log( [ "reduce结果" ,concat_reduce(arr2,arr1)].join(":"));//1,2,3,4,5,[6,7,8]]
/reduce 同样也只能连接两个数组
//5 ,使用apply 方法
arr1 = [1,2,3,[ 'a','b']]; arr2 = [ 'a','b'];
function concat_apply() {
    // return  Array.prototype.push.apply(arr1,arr2);
    return Array.prototype.concat.apply([], arguments)
  }
console.log( [ "apply方法" , concat_apply([[1, 2],[3, 4, 5], [6, 7, 8, 9,[11,12,[13]]],10] ,arr2)].join(":") ) ;
///apply方法总结,简洁高效,且能实现多个数组合并,并且能够实现深度嵌套,注意最后还是使用了concat哦,换成push是不可以的
  1. 嵌套数组合并
    上面是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是不用做任何改变的,本身就可以实现嵌套的合并。

  1. 多个数组合并
    原生的concat方法可以简单实现多个数组合并,比如
[1,2,3].concat([4,5,6],[6,7,8) ; // 1,2,3,4,5,6,7,8

至于其他方法,应该只是一个接口的问题,可以像下面这样实现
这里写图片描述
参数处理好了,上面两个问题整合一下就OK了,不过这样看来总结一下,还是
方法5比较好,再来瞻仰一下方法5 ,加深一下印象

function concat_apply() {
    return Array.prototype.concat.apply([], arguments)
  }

合并的时候获取还会牵涉到数组去重问题,下次再写喽。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值