提问人:JimminyCricket 提问时间:12/15/2022 最后编辑:JimminyCricket 更新时间:12/16/2022 访问量:56
重复数据删除时反转数据结构
Invert data structure while deduplicating
问:
我有一个复杂的任务,我正在努力寻找解决方案。我有以下数据结构
data = [
{
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
},
{
"id": 2,
"attributes": {
"name": "Important Topic",
"info": null,
"parentTopic": {
"data": {
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
}
}
}
},
{
"id": 3,
"attributes": {
"name": "Critical Topic",
"info": null,
"parentTopic": {
"data": {
"id": 2,
"attributes": {
"name": "Important Topic",
"info": null,
"parentTopic": {
"data": {
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
}
}
}
}
}
}
},
{
"id": 5,
"attributes": {
"name": "Another Important Topic",
"info": null,
"parentTopic": {
"data": {
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
}
}
}
},
{
"id": 6,
"attributes": {
"name": "Demo Demo Topic",
"info": null,
"parentTopic": {
"data": {
"id": 5,
"attributes": {
"name": "Another Important Topic",
"info": null,
"parentTopic": {
"data": {
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
}
}
}
}
}
}
},
{
"id": 7,
"attributes": {
"name": "Some Topic",
"info": null,
"parentTopic": {
"data": {
"id": 5,
"attributes": {
"name": "Another Important Topic",
"info": null,
"parentTopic": {
"data": {
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
}
}
}
}
}
}
},
{
"id": 9,
"attributes": {
"name": "Nice Topic",
"info": "Critical note",
"parentTopic": {
"data": {
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
}
}
}
},
{
"id": 10,
"attributes": {
"name": "Super Critical Topic",
"info": "Critical note",
"parentTopic": {
"data": {
"id": 9,
"attributes": {
"name": "Nice Topic",
"info": "Critical note",
"parentTopic": {
"data": {
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
}
}
}
}
}
}
},
{
"id": 11,
"attributes": {
"name": "Just Another Example Topic",
"info": null,
"parentTopic": {
"data": {
"id": 10,
"attributes": {
"name": "Super Critical Topic",
"info": "Critical note",
"parentTopic": {
"data": {
"id": 9,
"attributes": {
"name": "Nice Topic",
"info": "Critical note",
"parentTopic": {
"data": {
"id": 1,
"attributes": {
"name": "Mother of All Topics",
"info": "Notice",
"parentTopic": {
"data": null
}
}
}
}
}
}
}
}
}
}
}
},
{
"id": 22,
"attributes": {
"name": "Nested Important Topic",
"info": "",
"parentTopic": {
"data": null
}
}
},
{
"id": 23,
"attributes": {
"name": "Nice Topic",
"info": "",
"parentTopic": {
"data": {
"id": 22,
"attributes": {
"name": "Nested Important Topic",
"info": "",
"parentTopic": {
"data": null
}
}
}
}
}
},
{
"id": 24,
"attributes": {
"name": "Critical Top Level",
"info": "",
"parentTopic": {
"data": null
}
}
},
{
"id": 25,
"attributes": {
"name": "Nice Topic",
"info": "",
"parentTopic": {
"data": {
"id": 24,
"attributes": {
"name": "Critical Top Level",
"info": "",
"parentTopic": {
"data": null
}
}
}
}
}
},
{
"id": 26,
"attributes": {
"name": "Stakeholder Management",
"info": "Noice",
"parentTopic": {
"data": null
}
}
},
{
"id": 27,
"attributes": {
"name": "Conflict Resolution",
"info": "Watch out",
"parentTopic": {
"data": null
}
}
},
{
"id": 28,
"attributes": {
"name": "International Resolution",
"info": "Watch out",
"parentTopic": {
"data": null
}
}
},
{
"id": 29,
"attributes": {
"name": "Gadget Management",
"info": "",
"parentTopic": {
"data": {
"id": 25,
"attributes": {
"name": "Nice Topic",
"info": "",
"parentTopic": {
"data": {
"id": 24,
"attributes": {
"name": "Critical Top Level",
"info": "",
"parentTopic": {
"data": null
}
}
}
}
}
}
}
}
}
]
我尝试使用以下函数通过将其应用于字典数组来反转它,虽然由于某种原因它是一个递归函数,但它仅适用于一个嵌套级别。
// construct prefix
const getPrefix = (prefix, i) =>
prefix ? `${prefix}.${i + 1}` : `${i + 1}`;
// invert hierarchy
const invertHierarchy = (arr, parentTopic, prefix) =>
arr
.filter((e) => e.parentTopic.data?.id === parentTopic)
.map((e, i) => ({
...e,
index: getPrefix(prefix, i),
topics: invertHierarchy(arr, e.id, getPrefix(prefix, i)),
}));
我的目标输出结果如下所示
[
{
"id": 1,
"name": "Mother of All Topics",
"topics": [
{
"id": 2,
"name": "Important Topic",
"info": null,
"topics": [
{
"id": 3,
"name": "Critical Topic",
"topics": [
]
}
]
}
]
},
{
"id": 24,
"name": "Critical Top Level",
"topics": [
{
"id": 25,
"name": "Nice Topic",
"info": null,
"topics": [
{
"id": 29,
"name": "Gadget Management",
"topics": null
}
]
}
]
},
...
]
本质上,我的最终目标是最终得到倒置和重复数据删除的数据结构,其中每个父主题都位于顶部,所有子主题都正确嵌套在主题数组中。
如果有人能帮助解决这一挑战,我将不胜感激
!更新
[
{
id: 22,
attributes: {
name: 'Nested Important Topic',
info: '',
createdAt: '2022-12-06T13:37:51.626Z',
updatedAt: '2022-12-06T13:37:51.691Z',
parentTopic: [Object],
questions: [Object]
}
},
{
id: 23,
attributes: {
name: 'Nice Topic',
info: '',
parentTopic: {
data: {
id: 36,
name: "Critical High Level Topic",
info: ''
}
},
questions: [Object]
}
},
{
id: 25,
attributes: {
name: 'Nice Topic',
info: '',
parentTopic: [Object],
questions: [Object]
}
}
]
进一步更新!
输入
[
{
"id": 25,
"attributes": {
"name": "Nice Topic",
"info": "",
"parentTopic": {
"data": {
"id": 24,
"attributes": {
"name": "Critical Top Level",
"info": "",
"parentTopic": {
"data": null
}
}
}
}
}
},
{
"id": 23,
"attributes": {
"name": "Nice Topic",
"info": "",
"parentTopic": {
"data": {
"id": 22,
"attributes": {
"name": "Nested Important Topic",
"info": "",
"parentTopic": {
"data": null
},
}
}
},
}
},
{
"id": 22,
"attributes": {
"name": "Nested Important Topic",
"info": "",
"parentTopic": {
"data": null
}
}
}
],
输出!
[
{
"id": 24,
"name": "Critical Top Level",
"info": "",
"topics": [
{
"id": 25,
"name": "Nice Topic",
"info": "",
"topics": []
}
]
},
{
"id": 22,
"name": "Nested Important Topic",
"info": "",
"topics": [
{
"id": 23,
"name": "Nice Topic",
"info": "",
"topics": []
}
]
},
{
"id": 22,
"name": "Nested Important Topic",
"info": "",
"topics": []
}
],
答:
1赞
trincot
12/15/2022
#1
您的输入结构看起来像是具有重复的对象,并且可能最初具有对同一对象的重复引用(因此不是类似 JSON 的)。
我假设,如果在输入的一个区域中我们看到 24 是 25 的父节点,那么当我们在其他地方遇到节点 25 时也是如此。换言之,一个项目只有一个父项。
您可以反转数据结构,方法是首先在按对象的 id 键控的 Map 中收集对象,然后将每个 id 与具有 和 属性的新对象相关联。前两个可以立即设置,而属性将以空数组开始。id
name
topics
topics
对于每个对象,您可以递归地遍历祖先的路径,然后在回溯时将项目存储在父级的数组中。topics
下面是一个实现:
function reverseGraph(data) {
const rootTopics = [];
const map = new Map([[undefined, rootTopics]]);
function upward({id, attributes: {name, parentTopic: {data: parent}}}) {
if (map.has(id)) return map.get(id);
const topics = [];
map.set(id, topics);
(parent ? upward(parent) : rootTopics).push({id, name, topics});
return topics;
}
data.forEach(upward);
return rootTopics;
}
// Your example data:
const data = [{"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}},{"id": 2,"attributes": {"name": "Important Topic","parentTopic": {"data": {"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}}}}},{"id": 3,"attributes": {"name": "Critical Topic","parentTopic": {"data": {"id": 2,"attributes": {"name": "Important Topic","parentTopic": {"data": {"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}}}}}}}},{"id": 5,"attributes": {"name": "Another Important Topic","parentTopic": {"data": {"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}}}}},{"id": 6,"attributes": {"name": "Demo Demo Topic","parentTopic": {"data": {"id": 5,"attributes": {"name": "Another Important Topic","parentTopic": {"data": {"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}}}}}}}},{"id": 7,"attributes": {"name": "Some Topic","parentTopic": {"data": {"id": 5,"attributes": {"name": "Another Important Topic","parentTopic": {"data": {"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}}}}}}}},{"id": 9,"attributes": {"name": "Nice Topic","info": "Critical note","parentTopic": {"data": {"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}}}}},{"id": 10,"attributes": {"name": "Super Critical Topic","info": "Critical note","parentTopic": {"data": {"id": 9,"attributes": {"name": "Nice Topic","info": "Critical note","parentTopic": {"data": {"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}}}}}}}},{"id": 11,"attributes": {"name": "Just Another Example Topic","parentTopic": {"data": {"id": 10,"attributes": {"name": "Super Critical Topic","info": "Critical note","parentTopic": {"data": {"id": 9,"attributes": {"name": "Nice Topic","info": "Critical note","parentTopic": {"data": {"id": 1,"attributes": {"name": "Mother of All Topics","parentTopic": {"data": null}}}}}}}}}}}},{"id": 22,"attributes": {"name": "Nested Important Topic","parentTopic": {"data": null}}},{"id": 23,"attributes": {"name": "Nice Topic","parentTopic": {"data": {"id": 22,"attributes": {"name": "Nested Important Topic","parentTopic": {"data": null}}}}}},{"id": 24,"attributes": {"name": "Critical Top Level","parentTopic": {"data": null}}},{"id": 25,"attributes": {"name": "Nice Topic","parentTopic": {"data": {"id": 24,"attributes": {"name": "Critical Top Level","parentTopic": {"data": null}}}}}},{"id": 26,"attributes": {"name": "Stakeholder Management","info": "Noice","parentTopic": {"data": null}}},{"id": 27,"attributes": {"name": "Conflict Resolution","parentTopic": {"data": null}}},{"id": 28,"attributes": {"name": "International Resolution","parentTopic": {"data": null}}},{"id": 29,"attributes": {"name": "Gadget Management","parentTopic": {"data": {"id": 25,"attributes": {"name": "Nice Topic","parentTopic": {"data": {"id": 24,"attributes": {"name": "Critical Top Level","parentTopic": {"data": null}}}}}}}}}];
const result = reverseGraph(data);
console.log(result);
评论
0赞
JimminyCricket
12/16/2022
感谢您的解决方案@trincot,但不幸的是,我认为它假设所有嵌套项目至少应该存在于顶层,因为当我通过一个字典时,假设第一个级别中从未出现过第三个嵌套级别,它会抛出一个错误,说无法读取未定义的属性。我将编辑我的问题并添加数据结构示例
0赞
trincot
12/16/2022
“我认为它假设”:我把它列为假设,是的。感谢您更新您的问题,因为在原文中就是这种情况。
0赞
trincot
12/16/2022
我更新了我的答案,不再做出这个假设。
0赞
JimminyCricket
12/16/2022
非常感谢@trincot,这确实有助于消除这种假设,但我认为关于主题值的顺序还有一个假设。我用数据字典在问题中进行了另一次更新。基本上,它会在浏览数据后保留重复项。你认为你也可以帮忙解决这个问题吗?
0赞
trincot
12/16/2022
哦,所以有时一个节点在顶层重复,有时不是......我已经相应地更新了我的答案。
上一个:递归计算嵌套数组的数量
评论
[Object]