开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
前言
通常我们在项目经常会遇到嵌套结构的数组数据,对于一些嵌套层级不多的数据,我们比较好处理,但是对于一些嵌套层级比较深的数据,我们在处理数据的时候会比较麻烦,有的时候甚至会花费比较多的时间来处理这些数据,本文今天就来探讨一下,是否可以快速的来对这些数据做处理。
处理方法
对于一般的嵌套数据,形如 [ [] ] 数组套数组这种,我们在能够使用ES6 语法的情况下,可以直接使用flat 方法来对数据进行拉平。
const arr = [[1, 2, [1]], 2];
const newArr = arr.flat(); // [1, 2, 1, 2];
在使用flat 方法的情况,我们还可以传值,用来控制我们需要拉平的次数
const arr = [[1, 2, [1]], 2];
const newArr = arr.flat(1); // [1, 2, [1], 2];
const newArr2 = arr.flat(2); // [1, 2, 1, 2];
那么当我们不使用ES6 的语法,直接使用ES5 的语法,又该怎么去处理呢?
答案很简单,只需要参考下面写法:
const myFlat = (arr) => {
return arr.reduce((acc, cv, index) => {
const value = Array.isArray(cv) ? myFlat(cv) : [cv];
return [
...acc,
...value
]
}, [])
}
const arr = [[1, 2, [1]], 2];
const newArr = myFlat(arr); // [1, 2, 1, 2];
那么,如果我们需要对层级进行控制,又该怎么办呢?
const myFlat = (arr, depth) => {
if (depth <= 0) return arr;
return arr.reduce((acc, cv, index) => {
const value = Array.isArray(cv) ? myFlat(cv, depth-1) : [cv];
return [
...acc,
...value
]
}, [])
}
const arr = [[1, 2, [1]], 2];
const newArr = myFlat(arr, 1); // [1, 2, [1], 2];
const newArr2 = myFlat(arr, 2); // [1, 2, 1, 2];
项目应用
但是通常我们在项目中遇到的嵌套数据比较少是 [ [] ] 数组直接嵌套数据,可能更多的是Tree 结构的数据:
[
{
value: 'a',
label: 'a',
children: [
{
value: 'a-1',
label: 'a-1'
}
]
}
]
当我们遇到这样的数据结构的时候,只需要将上面ES5 的方法做一定的变形处理即可:
const myFlat = (options = [], parentId) => {
return options?.reduce((acc, cv, index) => {
return [
...acc,
{ ...cv, parentId },
...myFlat(cv.children, cv.value)
]
}, []);
}
const options = [
{
value: 'a',
label: 'a',
children: [
{
value: 'a-1',
label: 'a-1'
}
]
}
];
const newOptions = myFlat(options);
/**
[
{
value: 'a',
label: 'a',
children: [
{
value: 'a-1',
label: 'a-1'
}
]
},
{
value: 'a-1',
label: 'a-1',
parentId: 'a'
}
]
*/
至此,我们就可以对一定的嵌套数据进行拉平处理,方便我们在一层数组下面,进行查找数据和匹配数据。
拉平数组反向构建Tree数组
在项目中,我们有的时候可能对拉平后的数组做了一定的处理,然后我们需要将拉平后的数组反向构建成Tree 结构的数组,那么,我们只需要将拉平后的数组做如下处理即可:
const buildTree = (arr) => {
const root = { id: 'root', children: [] };
const nodes = { [root.id]: root };
const items = arr.map(item => ({ ...item, children: [] }));
for (const item of items) {
const { value, label, children } = item;
const parentId = item.parentId ?? root.id;
const parent = nodes[parentId] ?? items.find(i => i.value === parentId);
nodes[value] = { ...item };
parent.children.push(item);
}
return root.children;
}
const arr = [
{
value: 'a',
label: 'a',
children: [
{
value: 'a-1',
label: 'a-1'
}
]
},
{
value: 'a-1',
label: 'a-1',
parentId: 'a'
}
];
const newArr = buildTree(arr);
/**
[
{
value: 'a',
label: 'a',
children: [
{
value: 'a-1',
label: 'a-1',
parentId: 'a',
children: []
}
]
},
]
*/
总结
至此,我们知道了如何将嵌套数组进行拉平,以及如何将对应的拉平数组重新构建成Tree 结构的数组。这些方法对于我们在项目中碰到对应的结构数据,还是非常有用的。