JavaScript数组要领之数组兼并

网易前端口试的时刻,口试官问我有几种数组兼并的要领,当时第一回响反映就是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比较好用。

    原文作者:侯贝贝
    原文地址: https://segmentfault.com/a/1190000006751088
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞