数组的扁平化即为将一个嵌套多层的数组转换为只有一层的数组。
[1, [2]] => [1,2]
[[1, 2], [3, 4]] => [1, 2, 3, 4]
[1, 2, [3, 4, [5, 6]]] => [1, 2, 3, 4, 5, 6]
方法一:递归
思路:通过遍历最外层数组的每一个元素,看看是否还是数组,如果是的话,继续递归执行,不是的话,放到最后的结果数组当中。
// 1. 普通方法 递归
function flattenMd1() {
let result = [];
return function flatten(arr) {//闭包
arr.forEach(item => {
if (Array.isArray(item)) { //如果是数组的话,递归调用
flatten(item);
} else {
result.push(item); //如果不是数组,直接放入结果中
}
})
return result;
}
}
var ary = [1, [2, [3, [4, 5]]], 6];
console.log(flattenMd()(ary)); //函数柯里化 部分求值 打印结果:[ 1, 2, 3, 4, 5, 6 ]
方法二:concat
Array.concat(arr1,arr2...),合并两个或多个数组,生成一个新的数组。原数组不变。
//2.concat 与方法1类似 没用闭包
function flattenMd(arr) {
let result = []; // 利用函数作用域保存result,写成 var result = [] 也可
arr.forEach(item => {
if (Array.isArray(item)) {
result = result.concat(flattenMd(item));
} else {
result.push(item);
}
})
return result;
}
方法三:reduce
用reduce函数进行遍历,把prev
的初值赋值为[],如果当前的值是数组的话,那么我们就递归遍历它的孩子,如果当前的值不是数组,那么我们就把它拼接进数组里。
Array.prototype.reduce()方法介绍:
const arr = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue; console.log(arr.reduce(reducer)); //10,即1 + 2 + 3 + 4 console.log(arr.reduce(reducer, 6));//16,即6 + 1 + 2 + 3 + 4
第二个参数currentValue是当前的元素,而第一个参数accumulator总是返回每一次执行reducer函数的返回值,如此一次次累加起来。
reduce方法接收两个参数:reduce(callback,initialValue)
- callback(accumulator,currentValue, index,arr) : 执行于每个数组元素的函数;
- initialValue : 传给callback的初始值。
//3. reduce
function flat(arr) {
return arr.reduce(function (prev, cur) {
return prev.concat(Array.isArray(cur) ? flat(cur) : cur);
}, [])
}
let arr = [[1, 2, [3, 4], 5], [6, 7, 8], [[9, 10], 11]];
console.log(flat(arr)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
方法四:展开运算符
ES6 增加了展开运算符,用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
使用扩展运算符可以展开数组,再用concat()可以合并数组,但只操作一次的结果只能展开一层。
//只能展开一层 function flatten(array) { return [].concat(...array); } let array = [1, [[2, 3], 4]]; console.log(flatten(array)); // 打印[1, [2, 3], 4]
要完全展开需要对嵌套的数组遍历:
some() 方法:用于检测数组中的元素是否满足指定条件(函数提供)。它返回的是一个Boolean类型的值。
function flatten(arr) {
// 先用some()检测数组中的元素是否为一个数组
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
let arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
方法五:join和split组合
只适用于数组元素全部为数字的情况下
join() 方法:用于把数组中的所有元素放入一个字符串,元素通过指定的分隔符进行分隔
split()方法:用于把一个字符串分割成字符串数组
// 5. join和split组合
//[ '1', '2', '3', '4', '5', '6' ] 得到的是字符串数组,要用parseInt再转换成数值才行
function flattenMd5(arr) {
return arr.join().split(',').map(item => parseInt(item));
//join() 方法用于把数组中的所有元素放入一个字符串 默认用,隔开
}
var ary = [1, [2, [3, [4, 5]]], 6];
console.log(flattenMd5(ary)); //打印结果:[ 1, 2, 3, 4, 5, 6 ]