用于压平嵌套数组并跟踪所有父节点的递归函数(Javascript)



Hi我有一个函数,它接受包含子节点的嵌套父数组并将其展开。但是,我也想跟踪它的所有高级节点ID。

示例数据结构:

[{
id: 1,
type: "group",
name: "Colors",
items: [
{ id: 2, type: "item", name: "Red", items: [] },
{ id: 3, type: "item", name: "Purple2", items: [] },
{
id: 4,
type: "item",
name: "Black",
items: [
{
id: 5,
type: "item",
name: "Purple3",
items: [],
},
{ id: 6, type: "item", name: "Purple4", items: [] },
],
},
],
}]

这是当前的最终结果(这正是我想要实现的(,但下面的函数可能会被重构。

{id: 1, name: "Colors", depth: 1, parentId: null, main: []}
1: {id: 2, name: "Red", depth: 2, parentId: 1, main: [1]}
2: {id: 3, name: "Purple2", depth: 2, parentId: 1, main: [1]}
3: {id: 4, name: "Black", depth: 2, parentId: 1, main: [1]}
4: {id: 5, name: "Purple3", depth: 3, parentId: 4, main: [1,4]} // main stores id of all higher parents e.g. id 4 = "black" and parent of 4 = "Colors"
5: {id: 6, name: "Purple4", depth: 3, parentId: 4, main: [1,4]}

我当前的扁平阵列功能:

const flattenArr = (data, depth = 1, parent = null) => {
const result = [];
data.forEach((item) => {
const { id, name, items } = item;
result.push({
id,
name,
depth,
parentId: parent,
main: [],
});
if (items) result.push(...flattenArr(items, depth + 1, item.id));
});
return result;
};

下面的函数用于跟踪所有父ID。然而,它似乎不是我能使用的最理想的解决方案,因此我想知道它是否可以改进,是否可以在一个递归函数中完成。

const collectParents = (arr) => {
for (let b = 0; b < arr.length; b++) {
if (arr[b].depth !== 1) {
arr[b].main.push(
...arr[b - 1].main,
arr[b - 1].depth === arr[b].depth - 1 ? arr[b - 1].id : null
);
}
}
arr.forEach((x) => (x.main = x.main.filter((i) => i !== null)));
};

您可以使用reduce方法创建递归函数,并向下传递父id和以前id的数组。

const data = [{"id":1,"type":"group","name":"Colors","items":[{"id":2,"type":"item","name":"Red","items":[],"top":{}},{"id":3,"type":"item","name":"Purple2","items":[]},{"id":4,"type":"item","name":"Black","items":[{"id":5,"type":"item","name":"Purple3","items":[]},{"id":6,"type":"item","name":"Purple4","items":[]}]}]}]
function flatten(data, depth = 0, parentId = null, main = []) {
return data.reduce((r, { items, id, ...rest }) => {
const obj = { ...rest, id, depth, parentId, main }
r.push(obj)

if (items.length) {
r.push(...flatten(items, depth + 1, id, [...main, id]))
}

return r;
}, [])
}
const result = flatten(data)
console.log(result)

您不能将Array#flatMapmaindepth进行闭包运算。

const
flat = (main = [], depth = 1,) => ({ top, type, items = [], ...o }) => [
{ ...o, depth, parentId: main[0] ?? null, main },
...items.flatMap(flat([...main, o.id], depth + 1))
],
tree = [{ id: 1, type: "group", name: "Colors", items: [{ id: 2, type: "item", name: "Red", items: [], top: new Set() }, { id: 3, type: "item", name: "Purple2", items: [] }, { id: 4, type: "item", name: "Black", items: [{ id: 5, type: "item", name: "Purple3", items: [] }, { id: 6, type: "item", name: "Purple4", items: [] }] }] }],
result = tree.flatMap(flat());
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

最新更新