如何用对象作为嵌套数组重构2个数组?



目标是创建一个新的嵌套数组基于两个平面数组的对象。如果列表B中的id与列表a中的refId匹配,则该对象将作为子对象添加到列表a中的对象。这将创建一个新数组,深度为2层,如示例所示。

但是在List B中,有些对象的id与其兄弟对象的id匹配。如果是这种情况,代码应该找到匹配,然后将它们添加为父对象的子对象的子对象。因此,有3个层次。代码应该继续嵌套,直到没有可能的匹配。

如何修改下面的代码,以嵌套任何#的层次深度基于匹配id和refId ?

// TOP LEVEL
const listA = [ 
{ 
"id": 23,
"refId": 23, 
"name": 'list A #1',
"isNested": false,
"depth": 1,
"children": []
}, 
{ 
"id": 25,
"refId": 25, 
"name": 'list A #1',
"isNested": false,
"depth": 1,
"children": []
}
]
// NO HEIRARCHY
const listB = [ 
{ 
"id": 23,
"refId": 1234,
"name": "test 1",
"isNested": true, 
"depth": 2, 
"children": []
},
{ 
"id": 25,
"refId": 1212,
"name": "test 1",
"isNested": true, 
"depth": 2, 
"children": []
},
{ 
"id": 1234,
"refId": 4324,
"depth": 3,
"name": "test 2",
"isNested": true, 
"children": []
}, 
{ 
"id": 1234,
"refId": 5678,
"depth": 3,
"name": "test 3",
"isNested": true, 
"children": []
}
]
const nestedArr = listA.map(
({ id, name, refId, children }) => {
return {
id,
name,
refId,
children: listB.filter((b) => {
return b.id == refId ? b : ''
}),
}
}
)
console.log(nestedArr)

如果您的refs是有序的,您可以做以下操作:

  • 连接两个数组
  • 对于每个元素,
    • 将ref存储在Map中,以便以后可以轻松访问
    • 如果id === refId,则将其作为顶级ref
    • 如果没有,查找它的父元素并将其推入children数组
const refs = new Map();
const nestedArr = [];
for (const ref of listA.concat(listB)) {
refs.set(ref.refId, ref);

if (ref.id !== ref.refId) {
refs.get(ref.id).children.push(ref);
} else {
nestedArr.push(ref);
}
}
console.log(nestedArr)

下面是一个可运行代码片段:

// TOP LEVEL
const listA = [ 
{ 
"id": 23,
"refId": 23, 
"name": 'list A #1',
"isNested": false,
"depth": 1,
"children": []
}, 
{ 
"id": 25,
"refId": 25, 
"name": 'list A #1',
"isNested": false,
"depth": 1,
"children": []
}
]
// NO HEIRARCHY
const listB = [ 
{ 
"id": 23,
"refId": 1234,
"name": "test 1",
"isNested": true, 
"depth": 2, 
"children": []
},
{ 
"id": 25,
"refId": 1212,
"name": "test 1",
"isNested": true, 
"depth": 2, 
"children": []
},
{ 
"id": 1234,
"refId": 4324,
"depth": 3,
"name": "test 2",
"isNested": true, 
"children": []
}, 
{ 
"id": 1234,
"refId": 5678,
"depth": 3,
"name": "test 3",
"isNested": true, 
"children": []
}
];
const refs = new Map();
const nestedArr = [];
for (const ref of listA.concat(listB)) {
refs.set(ref.refId, ref);

if (ref.id !== ref.refId) {
refs.get(ref.id).children.push(ref);
} else {
nestedArr.push(ref);
}
}
console.log(nestedArr)

注意:这会改变原来的元素

您可以使用Map构造函数创建一个由所有refId键接的Map,并将相应的节点对象与它们关联起来。然后迭代第二个列表以生成附件。

这将改变现有的children数组,因此listA将得到结果:

const listA = [{"id": 23,"refId": 23,"name": 'list A #1',"isNested": false,"depth": 1,"children": []},{"id": 25,"refId": 25,"name": 'list A #1',"isNested": false,"depth": 1,"children": []}];
const listB = [{"id": 23,"refId": 1234,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 25,"refId": 1212,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 1234,"refId": 4324,"depth": 3,"name": "test 2","isNested": true,"children": []},{"id": 1234,"refId": 5678,"depth": 3,"name": "test 3","isNested": true,"children": []}];
const map = new Map(listA.concat(listB).map(node => [node.refId, node]));
for (const {id, refId} of listB) map.get(id).children.push(map.get(refId));
console.log(listA);

如果您不想改变原始输入,那么请确保创建新的children数组:

const listA = [{"id": 23,"refId": 23,"name": 'list A #1',"isNested": false,"depth": 1,"children": []},{"id": 25,"refId": 25,"name": 'list A #1',"isNested": false,"depth": 1,"children": []}];
const listB = [{"id": 23,"refId": 1234,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 25,"refId": 1212,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 1234,"refId": 4324,"depth": 3,"name": "test 2","isNested": true,"children": []},{"id": 1234,"refId": 5678,"depth": 3,"name": "test 3","isNested": true,"children": []}];
const map = new Map(listA.concat(listB).map(node => [node.refId, {...node, children:[]}]));
for (const {id, refId} of listB) map.get(id).children.push(map.get(refId));
const nestedListA = listA.map(({id}) => map.get(id));
console.log(nestedListA);

最新更新