我有一系列消息,其中包含唯一的数字ID,唯一的ID和非唯一的"以回复"引用其他消息的字段。从这个目标,我试图找到所有树的根,以及与这些树相对应的所有孩子。我发现返回包含一系列节点及其相应子节点的对象相对容易,但我无法以有效的方式合并它们。不幸的是,这棵树可能有数千个深度,或只是一个层次,这使得任务变得更加困难。
let exampleTree = {
1: {
'ID': 'IDONE',
'IN_REPLY_TO': undefined
},
3: {
'ID': 'IDTHREE',
'IN_REPLY_TO': 'IDONE'
},
7: {
'ID': 'IDSEVEN',
'IN_REPLY_TO': 'IDTHREE'
},
8: {
'ID': 'IDEIGHT',
'IN_REPLY_TO': 'IDTHREE'
}
}
// should return { 1: [3, 7, 8] }
function generateMap(tree) {
let convert = {}
let mapped = {}
for (let id in tree) {
if (typeof tree[id].IN_REPLY_TO != 'undefined') {
if (typeof mapped[tree[id].IN_REPLY_TO] != 'undefined') {
mapped[tree[id].IN_REPLY_TO].push(tree[id].ID)
} else {
mapped[tree[id].IN_REPLY_TO] = [tree[id].ID]
}
}
convert[tree[id].ID] = id
}
let uidMapped = {}
for (let id in mapped) {
uidMapped[convert[id]] = mapped[id].map(function(value) { return convert[value] })
}
return uidMapped
}
console.log(generateMap(exampleTree))
// currently returns { 1: [3], 3: [7, 8] }
希望上面的例子清楚地说明了我想要完成的事情。七个和八个都是三个孩子,而后者又是一个孩子。我试图将这两者结合在一起。
答案 0 :(得分:1)
让我们将此任务分成多个步骤并命名:
message.ID
与其数字id
相关联。每个id
对应一个树节点。 id
为undefined
。您的generateMap
计算 1。您仍然需要展平树,这可以通过递归函数轻松完成 - 请参阅下面的findAllChildren
。
以下是一个示例实现。我试图评论所有步骤,并为每个涉及的实体找到有意义的名称:
// Find all children below a given root:
function findAllChildren(root, children) {
let result = children[root] || [];
for (let child of result) {
result = result.concat(findAllChildren(child, children));
}
return result;
}
// Find all root messages and their children:
function findRootAndChildMessages(messages) {
// 1. Link each id to its respective message.ID:
let ids = {};
for (let [id, message] of Object.entries(messages)) {
ids[message.ID] = id;
}
// 2. Link children to parents:
let children = {};
for (let [id, message] of Object.entries(messages)) {
let parent_id = ids[message.IN_REPLY_TO];
children[parent_id] = children[parent_id] || [];
children[parent_id].push(id);
}
// 3. Link each child to its non-undefined root:
let result = {};
for (let child of children[undefined]) {
result[child] = findAllChildren(child, children);
}
return result;
}
// Example:
let messages = {
1: {
'ID': 'IDONE',
'IN_REPLY_TO': undefined
},
3: {
'ID': 'IDTHREE',
'IN_REPLY_TO': 'IDONE'
},
7: {
'ID': 'IDSEVEN',
'IN_REPLY_TO': 'IDTHREE'
},
8: {
'ID': 'IDEIGHT',
'IN_REPLY_TO': 'IDTHREE'
}
}
console.log(findRootAndChildMessages(messages));