数组扁平化的5种方法

319 阅读2分钟

方式1:递归法

思路: 创建一个新数组result, 遍历源数组的每一项,判断该项是否为一个数组,如果是一个数组,则递归处理该项数组,如果不是数组,则把该项push到result中,最终将result返回即可。

function flat1(source) {
	if (!source.length) return [];
	const result = [];

	function rec(arr) {
		arr.forEach(el => {
                        //el为数组,递归
			if (Array.isArray(el) && el.length) {
				rec(el);
                        //el不为数组 
			} else { 
				result.push(el);
			}
		});
	}
	rec(source);
	return result;
}

方式2:栈方法

思路: 利用处理,每次出栈的元素叫做current,current如果为数组,那么遍历该数组,并把数组的每一项推到栈顶,如果不是数组,则把该项push到result中,最终将result返回即可。

function flat2(source) {
	if (!source.length) return [];
	const result = [];

	const stack = [source];
	while (stack.length) {
		const current = stack.shift();
		if (Array.isArray(current) && current.length) {
			// 方式1:需要反转
			current.reverse().forEach(el => {
				stack.unshift(el);
			});
			// 方式2:优雅写法
			// stack.unshift(...current);
		} else {
			result.push(current);
		}
	}
	return result;
}

方式3:利用字符串(该方法要求数组的元素为基本类型)

思路: JS数组转字符串会有一个特点,例如 [0, 1, 2, [3, 4], 5] 转为字符串之后变成 '0, 1, 2, 3, 4, 5'。 注意如果最终每个元素都为String类型,根据需求决定是否要转Number

function flat3(source) {
	if (!source.length) return [];
	return str.split(",").map(el => el * 1); // 注意el转为数字
      //正则替换的思路亦可 
      //const str = JSON.stringify(source);
      //return str.replace(/(\[|\])/g, "").split(",").map(el => el * 1); 
}

方式4:利用原生flat方法

思路: 利用JS数组的flat方法,该方法有一个特点,就是每执行都会帮数组降一维,就是 [0, [1, 2, [3, 4]], 5] 执行flat之后变成 [0, 1, 2, [3, 4], 5][0, 1, 2, [3, 4], 5] 再执行flat之后变成 [0, 1, 2, 3, 4, 5]。 根据这个思路,可以执行flat(Infinity),从而实现数组的扁平化。

image.png

function flat4(source) {
	return result = source.flat(Infinity);;
}

方式5:利用扩展运算符

思路:while重复解构,直至数组的每一项都不为数组。

//该方法会改变原数组,可以自行深拷贝再做处理
function flat5(source) {
	while (source.some(Array.isArray)) {
		source = [].concat(...source);
	}
	return source;
}

测试

说明: 方法3要求数组的元素为基本类型,数组为引用类型的请自行校验,本人校验结果均无误(有误请在评论区留代码,感谢)。

console.log(flat1([0, [1, 2, [3, 4]], 5])); //[0, 1, 2, 3, 4, 5]
console.log(flat2([0, [1, 2, [3, 4]], 5])); //[0, 1, 2, 3, 4, 5]
console.log(flat3([0, [1, 2, [3, 4]], 5])); //[0, 1, 2, 3, 4, 5]
console.log(flat4([0, [1, 2, [3, 4]], 5])); //[0, 1, 2, 3, 4, 5]
console.log(flat5([0, [1, 2, [3, 4]], 5])); //[0, 1, 2, 3, 4, 5]