zoukankan      html  css  js  c++  java
  • Javascript实现的数组降维——维度不同,怎么谈恋爱(修订版)

    数组的元素可能是数组,这样一层层嵌套,可能得到一个嵌套很深的数组,数组降维要做的事就是把嵌套很深的数组展开,一般最后得到一个一维数组,其中的元素都是非数组元素,比如数组[1, [2, 3, [4, 5], 6], 7, 8]降维展开后是[1, 2, 3, 4, 5, 6, 7, 8].

    1.普通方法

    function flattenMd(arr){
        var result=[]
        function flatten(arr){
            for (var i = 0; i < arr.length; i++) {
                if (Array.isArray(arr[i])) {
                    flatten(arr[i]);
                }else{
                    result.push(arr[i]);
                }        
            }
        }
        flatten(arr);
        return result;
    }
    var arr=[1, [2, 3, [4, 5], 6], 7, 8]
    console.log(flattenMd(arr));[ 1, 2, 3, 4, 5, 6, 7, 8 ]
    

    备注:这里我使用了Array.isArray()方法来检测对象时候是数组,没有考虑ES5以下的兼容性,关于js对象类型的检测可以参考我的另一篇博文Javascript数据类型检测,当然了如果支持ES5的话,还可以直接使用数组的迭代方法forEach(或map、reduce等),Es6中还有for···in可以使用,这里就不赘述了。
    这个方法需要定义两个函数,其中flatten方法位于内部。还可以改造成闭包的形式

    function flattenMd(ret) {
        function flatten(arr) {
            arr.forEach(function(item) {
                (Array.isArray(item)) ? flatten(item) : ret.push(item);
            });
        }
        
        return function(arr) {
            flatten(arr);
            return ret;
        }
        
    }([]);
    var arr=[1, [2, 3, [4, 5], 6], 7, 8]
    console.log(flattenMd(arr));[ 1, 2, 3, 4, 5, 6, 7, 8 ]
    

    2.数组concat方法

    熟悉数组操作方法的开发人员应该知道数组concat方法的特性:传递给concat方法的参数序列中如果包含数组,则会将这个数组的每一项添加到结果数组中,这就使数组的这个方法具有了天然的展开二维数组的能力,比如:

    var colors=['red','green','blue'];
    var colors2=colors.concat('yellow',['black','brown']);
    console.log(colors2)//[ 'red', 'green', 'blue', 'yellow', 'black', 'brown' ]
    

    需要注意的是如果数组的元素还是数组则不会再展开了,也就是concat方法只能降低一维。借助concat方法,可以得到另一种二维数组降维方法。

    function flatten2d(arr) {
        var result = [];
        for(var i = 0; i < arr.length; i++) {
            result = result.concat(arr[i]);
        }
        return result;
    }
    

    上面的方法还可以进一步简化。我们知道apply方法是可以直接接受数组参数,这样我们连循环迭代都省了。

    function flatten2d(arr) {
        return Array.prototype.concat.apply([], arr);
    }
    

    网上很多博客说使用递归很容易将二维的降维改造成多维的降维,实际上操作起来是比较复杂的,因为没有现成的方法能够判断某个数组是不是二维数组,也就不能判断递归的结束条件了。所以对于多维数组的降维需要重新规划使用concat方法可以避免方法一中多出的内部函数
    对于多维数组

    function flattenMd(arr) {
        var result = [];
        for(var i = 0; i < arr.length; i++){
            if(arr[i] instanceof Array) {
                result = result.concat(flattenMd(arr[i]));
            }
            else {
                result.push(arr[i]);
            }
        }
        return result;
    }
    var arr=[1, [2, 3, [4, 5], 6], 7, 8]
    console.log(flattenMd(arr));[ 1, 2, 3, 4, 5, 6, 7, 8 ]
    

    3.数组join和split方法的结合(有缺陷)

    很多开发人员都知道数组的join方法可以将数组展开成字符串,但是不确定的是join方法能够展平数组,即使是多维数组,我们再使用split方法重新组合数组就行了。但是这个方法有天然缺陷,下面的例子中会看到

    function flattenMd(arr) {
       return arr.join().split(',');   
    }
    var arr=['1', [null, 3, [4, 5], {K:1}], undefined, 8]
    
    console.log(flattenMd(arr));//[ '1', '', '3', '4', '5', '[object Object]', '', '8' ]
    

    从结果可以看出,这样处理过后有几个缺点:一是所有类型的元素都会变成字符串;二是null、undefined会变成空字符串、对象会变成'[object Object]'。相当于调用了toString方法,当也不是说这个方法一无是处。对于同一种类型的元素,还是很有用处的,比如要求多维数组的最大值。

    function flattenMd(arr) {
       return arr.join().split(',');   
    }
    var arr=[1, [5, 3, [8, 5], 5,[15]], 9, 13]
    console.log(Math.max.apply(null,flattenMd(arr)));//15
    
    

    4.最佳实践方法

    function flatten(arr) {
        return arr.reduce((prev, cur) => {
            return plane.concat(Array.isArray(cur) ? flatten(cur) : cur);
        }, []);
    }
    
    function deepFlatten(arr) {
        flatten = arr => [].concat(...arr);
        return flatten(arr.map(item => (Array.isArray(item) ? deepFlatten(item) : item)));
    }
    

    参考
    优雅的数组降维——Javascript中apply方法的妙用

  • 相关阅读:
    《那些年啊,那些事——一个程序员的奋斗史》——35
    《那些年啊,那些事——一个程序员的奋斗史》——34
    《那些年啊,那些事——一个程序员的奋斗史》——36
    《那些年啊,那些事——一个程序员的奋斗史》——36
    《那些年啊,那些事——一个程序员的奋斗史》——35
    《那些年啊,那些事——一个程序员的奋斗史》——35
    《那些年啊,那些事——一个程序员的奋斗史》——36
    大内高手—常见内存错误
    [open source]Lrc歌词解析器发布
    大内高手—共享内存与线程局部存储
  • 原文地址:https://www.cnblogs.com/star91/p/avascript-shi-xian-de-shu-zu-jiang-weiwei-du-bu-to.html
Copyright © 2011-2022 走看看