JavaScript:将多维数组扁平化的方法

6,100 阅读2分钟

想必小伙伴们不管在实际开发的项目中,还是在面试中,都会遇见需要把多维数组展开为一维数组的问题,那么我们该如何去处理呢?我总结了几种常用且有效的方法,废话不多说,请往下看

方法一:ES6新增的数组扩展方法flat()

let arr = [1,2,3,[4,5],6];
let res = arr.flat();//[1,2,3,4,5,6]

可能会有小伙伴说flat()默认只能拉伸一层,那么如果我需要处理的是多层嵌套数组,也就是二维+的数组形式呢?针对这个问题我特意去翻了翻flat()的技术文档,得出的结论是:

let arr1 = [1,2,3,[4,5,[6,7]],8];
let res1 = arr.flat(3);//参数3代表三维数组的展开,结果为[1,2,3,4,5,6,7,8]

let arr2 = [1,2,3,[4,5,[6,7,[8]]],9];
let res2 = arr2.flat(4);//参数4代表思维数组的展开,结果为[1,2,3,4,5,6,7,8,9]

......

不过这样处理的话,对于已知的数组维度是可以处理的,那么对于未知嵌套层级的数组是相当不友好的,那么针对未知的多维嵌套数组我们应该用什么方法展开呢?看代码:

let arr3 = [1,2,3,[4,5,[6,7,[8]]],9];
let res3 = arr3.flat(Infinity);//参数为Infinity,结果为[1,2,3,4,5,6,7,8,9]

这样不管你要处理的数组是几层嵌套关系,都会处理成你想要的一维数组。

方法二:apply()结合concat()使用以展开成一维数组

let arr4 = [1,2,3,[4,5],6];
let res4 = [].concat.apply([],arr4);//结果为[1,2,3,4,5,6]

这个方法虽然可以处理,不过有一个缺陷需要指出,那就是该方法只能将二维数组展开为一维,二维以上的多维数组的处理就需要循环遍历一层层的使用该方法了,有点麻烦,如果想使用简单的方法,请参考方法一。

方法三:reduce()结合concat()方法

let arr5 = [[0, 1], [2, 3]];
let res5 = arr5.reduce(
  (acc, cur) => {
    return acc.concat(cur);
  }
);//结果为[0,2,3,4]

需要注意的是此方法和方法二类似,处理多维数组的时候需要进行其他处理。

方法四:针对方法一和方法二的缺陷,可以使用递归的方法进行展开

let arr6 = [1,2,[3,4,[5,6],7],8]
function flatten(arr){
	let res6 = [];
	for(let i=0; i < arr.length; i++){
		if(Array.isArray(arr[i])){
			res6 = res6.concat(flatten(arr[i])) 
		}else{
			res6.push(arr[i])
		}
	}
	return res6;
}
Flatten(arr6);//结果为[1,2,3,4,5,6,7,8]

方法五:使用toString()和split(',')方法

如果数组的元素都是数字,那么我们可以考虑使用 toString 方法,因为:toString会将数组中的数以逗号形式结合起来。toString()之后再split(',')转成数组,并将其转换回数字数组:

var arr = [1, [2, [3, 4],[5,[6],[7,8]]]];
var arrStr = arr.toString();
console.log(arrStr);//1,2,3,4,5,6,7,8
var strArr = arrStr.split(',');
console.log(strArr)//["1", "2", "3", "4", "5", "6", "7", "8"]

该方法只适用于数组内全部是数字的情况。

方法六:使用reduce和concat方法,结合递归,利用重写原型的另一种方法

Array.prototype.flatten=function(){
  return this.reduce(function(prev, cur) {
    var moreArr = [].concat(cur).some(Array.isArray); //判断cur是不是一个数组
    return prev.concat(moreArr ? cur.flatten() : cur);
  },[]);
};
var bbb = [1,2,3,[4,[5,6,[7,8]]]]
var ccc=bbb.flatten();
console.log(ccc);//结果为[1, 2, 3, 4, 5, 6, 7, 8]

方法七:es6扩展运算符

function flatten(arr){
  while(arr.some(item=>Array.isArray(item))){
    arr = [].concat(...arr);
  }
  return arr;
}
var sunArr = [1,2,3,[4,[5,[6]]]];
flatten(sunArr);//结果为 [1, 2, 3, 4, 5, 6]

OK,以上几种方法需要根据不同的需求进行选择使用,也欢迎小伙伴们在评论区补充讨论其他方法。