题外话:上班路上听 陈钢先生 的《人文通识》,今天是李叔同先生,也就是大家所熟知的弘一法师,讲的蛮有意思。
数组扁平化如下示例,简单来说就是展开。
var arr1 = [1, [2, 3], [[3, 4, 2], 1], 5, [3]]; => [1, 2, 3, 3, 4, 2, 1, 5, 3]
var arr2 = [1,['2', 3], [2], '2', 4] => [1, "2", 3, 2, "2", 4]
1.经典:递归
思路:循环数组,判断arr[i]是否是数组,是数组的话再次调用此函数。
function flatten(arr) {
var res = [];
for(var i = 0, len = arr.length; i < len; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(flatten(arr[i])); // concat不改变原数组,返回被连接数组的副本
} else {
res.push(arr[i]); // push直接操作原数组
}
}
return res;
}
2. reduce() 方法
reduce() 接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
接收四个参数,前两个必填,total 初始值,计算结束后的返回值;currentValue 当前元素;currentIndex 当前元素索引;
arr 元素所属数组对象;initialValue,累加器初始值。
function flatten(arr) {
return arr.reduce((pre, next) => {
return pre.concat(Array.isArray(next) ? flatten(next) : next);
}, [])
}
3. toString() // 别用 别用 别用
用此方法会改变数据类型,当你确定数组中每项数据类型都一样的时候(number or string)可以用一下,最好别用别用别用。
function flatten(arr) { // 这个对于 arr1 可行,对于arr2 致命。
return arr.toString().split(',').map(function(item){ // split之后是字符串 再转一下数字
return +item
})
}
4. ES6 flat()
flat(n)将每一项的数组偏平化,n默认是1,表示扁平化深度,Infinity无限次
flat()会跳过空格,返回新数组不改变原数组
function flatten(arr) {
return arr.flat(Infinity);
}
5. ES6 扩展运算符 ...
扩展运算符(...)只能展开一层,也要循环,思路同 1、2。
function flatten(arr) {
while(arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr); // 给原数组重新赋值
}
return arr;
}