首先什么是数组展开?
假如如今有这样一个需求:将后台的一个多重 List 数据,展开成一个 List 后,并去重后排序;javascript
["a", "b", ["c", "d"], [["d"],"e"], "f"] => ["a", "b", "c", "d", "e"];
复制代码
数组去重咱们前面在《JS专题之数组去重》已经讲过了,那么前一步的多重数组展开成单层数组,该如何处理呢?java
这就来到咱们所要探讨的数组展开了。
根据需求的特色,数组展开须要进行迭代和递归。数组
回答文章开头的问题:闭包
将多重数组转化成单层数组的过程就是数组展开,也叫做数组扁平化(flatten)app
最简单的思路:循环中判断,若是子元素是数组则递归。函数
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, 它能把数组的因此元素转化成用逗号隔开的字符串。post
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 转化为字符串的时候,不会区分字符串和数字类型,在进行区分数据类型的时候要注意。ui
上面的方法,咱们用 toString() 将数组转化为字符串,那么咱们也能够用 split 来作:this
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"]
复制代码
一样,这种字符串和数组互转的过程,不适合多种数据类型同时处理。spa
咱们注意到其实数组扁平化其实就是“迭代 + 拼接(累加) + 递归”的过程,数组 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 会遍历数组的每个元素,判断是否有元素都知足条件,最后返回布尔值。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"]
复制代码
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"]
复制代码
JS Array 对象提供了原生的能够实现扁平化的函数flat:详细说明见 MDN
var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];
// 2 表示深度
arr.flat(2) // [1, 2, 3, 4, "a", "b", "c", "d", "d", "e", "f"];
复制代码
数组扁平化其实就是利用元素迭代 + 元素拼接(叠加)+ 递归调用来对数组进行处理,达到将多层数组转换为单层数组的过程。 欢迎关注个人我的公众号“谢南波”,专一分享原创文章。