ES6+ flat()

1. 前言

在开发中有时会遇到对多维数组进行拍平处理,数组的拍平就是将一个嵌套多层的数组进行降维操作,也就是对数值进行扁平化。然而在 ES5 是没有方法能处理这样的需求的,大部分都会借助函数库的方式来实现。

本节我们要学习的是 ES6 提供的 flat() 方法,对多维数组进行扁平化操作,而且可以对数组中的空项进行移除。

2. ES5 中的处理方法

ES5 中没有类似的方法,如果要达到目标结果需要自己写函数针对性处理。

function flat(arr){
	if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
	let res = [];
	for(var i=0;i<arr.length;i++){
		if(arr[i] instanceof Array){
			res = res.concat(flat(arr[i]))
		}else{
			res.push(arr[i])
		}
	}
	return res;
};
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);	// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

上面的代码是实现了一个数组扁平化的方法,在里面我们会定义一个空数组然后递归地去调用 flat() 方法处理原数组中的每一项,如果传入的是元素是数组,则要继续递归处理,最终会得到一个一维的数组。此方法只能把任意维度的数组转化为一维数组,不能转化为指定维度的数组,如果需要的话还得继续处理。

由此可见,扁平化数组是一件很麻烦的事,ES6 提供的 flat() 方法完美地解决了扁平化数组所带来的问题,下面我们就来学习 flat() 方法吧。

3. 方法详情

3.1 语法使用

使用 flat() 方法会接收一个参数,这个参数是数值类型,是要处理扁平化数组的深度,生成后的新数组是独立存在的,不会对原数组产生影响。由此我们也可以使用它深拷贝一个数组,下文我们会用一个案例说明。

语法使用:

var newArray = arr.flat([depth])

参数解释:

参数 描述
depth 指定要提取嵌套数组结构的深度,默认值为 1

3.2 语法示例

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

上面的代码定义了一个层嵌套的数组,默认情况下只会拍平一层数组,也就是把原来的三维数组降低到了二维数组。在传入的参数为 2 时,则会降低两维,成为一个一维数组。

使用 Infinity,可展开任意深度的嵌套数组

var arr = [1, 2, [3, 4, [5, 6, [7, 8]]]];
arr.flat(Infinity);  // [1, 2, 3, 4, 5, 6, 7, 8]

3.3 数组空项

在数组中有空项的时候,使用 flat() 会将中的空项进行移除。

var arr = [1, 2, , 4, 5];
arr.flat();      // [1, 2, 4, 5]

上面的代码中,数组中第三项是空值,在使用 flat 后会对空项进行移除。

4. 案例:深拷贝数组

使用 flat() 方法有个很好用的场景,就是深拷贝数组。我们知道 flat() 拍平后的数组不会影响源数组,那么是不是我们可以传入参数 0 让其不做扁平化操作呢?答案是可以的:

var arr1 = [1, 2, [3, 4, [5, 6]]];
var arr2 = arr1.flat(0);
arr2.push(100)
console.log(arr1)		// [1, 2, [3, 4, [5, 6]]]
console.log(arr2)		// [1, 2, [3, 4, [5, 6]], 100]

上面的代码中我们传入了 0 作为数组扁平化的深度,也就是不处理,然后给得到的 arr2 数组添加元素,最后打印两个数组,可以看到 arr1 没有 100,这样就达到了使用 flat() 来进行数值的深拷贝。

4. 小结

本节介绍了对多维数组拍平的方法 flat(),并且可以对数组中的空项进行移除,这个方法可以使用在处理数组空项的操作中非常有用。另外,在开发中解决了一个重要的数组深拷贝问题,不妨使用此方法达到事半功倍的效果。