JS专题之数组睁开

媒介

起首什么是数组睁开?
如果如今有如许一个需求:将背景的一个多重 List 数据,睁开成一个 List 后,并去重后排序;

["a", "b", ["c", "d"], [["d"],"e"], "f"] => ["a", "b", "c", "d", "e"];

数组去重我们前面在《JS专题之数组去重》已讲过了,那末前一步的多重数组睁开成单层数组,该怎样处置惩罚呢?

这就来到我们所要讨论的数组睁开了。
依据需求的特性,数组睁开须要举行迭代和递归。

回复文章开首的题目:

将多重数组转化成单层数组的历程就是数组睁开,也叫作数组扁平化(flatten)

一、轮回加递归

最简朴的思绪:轮回中推断,如果子元素是数组则递归。

function flatten(origin) {
    var result = [];
    for(var i = 0; i< origin.length; i++) {
        var item = origin[i];
        if(Array.isArray(item)) {
            result = result.concat(flatten(item))
        } else {
            result.push(item);
        }
    }
    return result;
}

var arr = ["a", "b", ["c", "d"], [["d"],"e"], "f"];
flatten(arr);  // ["a", "b", "c", "d", "d", "e", "f"]

二、toString()

数组的原型对象上有一个要领,toString, 它能把数组的所以元素转化成用逗号离隔的字符串。

var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];  
arr.toString()  // "1,2,3,4,a,b,c,d,d,e,f"

// 所以,应用 split 先把字符串转化为单层数组,再举行处置惩罚。
const flatten = (origin) => origin.toString().split(',');  // ["1", "2", "3", "4", "a", "b", "c", "d", "d", "e", "f"]

因为 toString 转化为字符串的时刻,不会辨别字符串和数字范例,在举行辨别数据范例的时刻要注意。

三、split

上面的要领,我们用 toString() 将数组转化为字符串,那末我们也能够用 split 来做:

var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];
function flatten(arr) {
    return arr.join(',').split(',');  
} 
console.log(flatten(arr))。 // ["1", "2", "3", "4", "a", "b", "c", "d", "d", "e", "f"]

一样,这类字符串和数组互转的历程,不适合多种数据范例同时处置惩罚。

四、reduce

我们注意到实在数组扁平化实在就是“迭代 + 拼接(累加) + 递归”的历程,数组 reduce 要领既能够迭代又能够累加,适合做数组扁平化。

function flatten(origin){
  return origin.reduce(function(init, item){
    return init.concat(Array.isArray(item) ? flatten(item) : item)
  }, [])
}
var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];  
console.log(flatten(arr)) // [1, 2, 3, 4, "a", "b", "c", "d", "d", "e", "f"]

五、some + concat

some 会遍历数组的每个元素,推断是不是有元素都满足前提,末了返回布尔值。some 一旦返回真值后,厥后的元素就不会继承监测。

function flatten(origin) {
    while (origin.some(item => Array.isArray(item))){
    origin = [].concat.apply([], origin);
  }
  return origin;
}
var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];  
console.log(flatten(arr)) // [1, 2, 3, 4, "a", "b", "c", "d", "d", "e", "f"]

六、some + 扩大运算符

ES6 扩大运算符...能够将两重数组转换为单层数组:

[].concat(...[1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"]);  // [1, 2, 3, Array(1), "a", "b", "c", "d", Array(1), "e", "f"]

// 应用 some 要领,我们能够完成多重转换为单层:

function flatten(origin) { while(origin.some(item=> Array.isArray(item))) {
        origin = [].concat(...origin);
    } return origin;
}

var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];  
console.log(flatten(arr)) // [1, 2, 3, 4, "a", "b", "c", "d", "d", "e", "f"]

总结

数组扁平化实在就是应用元素迭代 + 元素拼接(叠加)+ 递归调用来对数组举行处置惩罚,到达将多层数组转换为单层数组的历程。

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