一、数组的扁平化
1. 使用 flat() 方法
Array.prototype.flat() 方法可以将多维数组转化为一维数组。flat() 方法的一个显著特点是,它支持指定扁平化的深度,默认为 1。
let arr = [1, [2, [3, [4]]]];
let flattenedArr = arr.flat(2); // 扁平化到深度 2
console.log(flattenedArr); // [1, 2, 3, 4]
// console.log(arr.flat(Infinity)); //如果不确定有多少层,可以填Infinity
2. 使用递归实现数组扁平化
当我们需要扁平化深度不确定的数组时,递归是一种非常实用的方法。通过递归处理每个数组元素,直到它不是数组为止。
function flatten(arr) {
let result = [];
for (let item of arr) {
if (Array.isArray(item)) {
result.push(...flatten(item)); // 递归处理数组
} else {
result.push(item); // 非数组元素直接添加到结果中
}
}
return result;
}
let arr = [1, {a: 1}, [2, [3, 4]]];
console.log(flatten(arr)); // [1, {a: 1}, 2, 3, 4]
3. 使用 toString() 方法
通过 toString() 方法将数组转换为字符串后,再通过 split() 方法分割成数组,得到一个一维数组。这种方法对于只有原始类型数据的数组有效。
let arr = [1, [2, [3, 4]]];
let flattenedArr = arr.toString().split(',').map(Number); // 转为字符串,再分割并转为数字
console.log(flattenedArr); // [1, 2, 3, 4]
4. 使用 while 循环和 concat() 方法
通过 while 循环判断数组中是否存在嵌套的数组,如果存在,则通过 concat() 方法展开数组直到没有嵌套数组为止。
function flatten2(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr); // 展开数组
}
return arr;
}
let arr = [1, [2, [3, 4]]];
console.log(flatten2(arr)); // [1, 2, 3, 4]
二、对象的扁平化
1. 递归实现对象的扁平化
通过递归的方式处理嵌套对象的每个键值对,最终生成一个包含所有嵌套路径的扁平化对象。
let obj = {
a: 1,
b: [1, 2, {c: 3}, [4]],
d: {
e: 2,
f: 3
},
g: null
};
function flatObj(target) {
let res = {};
function help(target, oldKey) {
for (let key in target) {
let newKey;
if (oldKey) { // 递归时,构造新的键名
if (Array.isArray(target)) {
newKey = `${oldKey}[${key}]`; // 数组的键名如 'b[2]'
} else {
newKey = `${oldKey}.${key}`; // 对象的键名如 'b.2'
}
} else {
newKey = key; // 最初的键名
}
if (Object.prototype.toString.call(target[key]) === '[object Object]' || Array.isArray(target[key])) {
help(target[key], newKey); // 递归处理嵌套对象或数组
} else {
res[newKey] = target[key]; // 将最终结果添加到结果对象中
}
}
}
help(target, ''); // 初始递归
return res;
}
console.log(flatObj(obj));
输出结果
{
'a': 1,
'b[0]': 1,
'b[1]': 2,
'b[2].c': 3,
'b[3][0]': 4,
'd.e': 2,
'd.f': 3
}