Javascript 如何在一个对象中查找多棵树的根
我有一系列消息,其中包含唯一的数字ID、唯一ID和非唯一ID,用于回复引用其他消息的字段。从这个对象中,我试图找到所有树的根,以及与这些树对应的所有子树。我发现返回一个包含一系列节点及其相应子节点的对象相对容易,但在高效地合并它们时遇到了困难。不幸的是,这棵树可能有几千层深,或者只有一层深,这使得任务相当困难Javascript 如何在一个对象中查找多棵树的根,javascript,node.js,tree,Javascript,Node.js,Tree,我有一系列消息,其中包含唯一的数字ID、唯一ID和非唯一ID,用于回复引用其他消息的字段。从这个对象中,我试图找到所有树的根,以及与这些树对应的所有子树。我发现返回一个包含一系列节点及其相应子节点的对象相对容易,但在高效地合并它们时遇到了困难。不幸的是,这棵树可能有几千层深,或者只有一层深,这使得任务相当困难 let exampleTree = { 1: { 'ID': 'IDONE', 'IN_REPLY_TO': undefined }, 3: {
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] }
希望上面的例子能清楚地说明我想要实现的目标。七岁和八岁都是三岁的孩子,而三岁又是一岁的孩子。我正在尝试将这两个步骤结合起来。让我们将此任务分为多个步骤,并命名为: 构建一棵树: 将每个message.ID与其数字ID关联。每个ID对应于一个树节点。 创建父节点到子节点的映射。 把树压平: 选择id未定义的树根。 对于其每个子级,递归地构建其所有子级的子级的列表。 您的generateMap计算1。您仍然需要展平树,这可以通过递归函数轻松完成-请参见下面的findAllChildren 下面是一个示例实现。我试图对所有步骤进行注释,并为每个涉及的实体找到有意义的名称: //查找给定根目录下的所有子目录: 函数findAllChildrenroot,children{ 让结果=子项[根]| |[]; 为了让孩子知道结果{ 结果=结果。ConcatFindAllChildrenChildrenChildrenChildren,children; } 返回结果; } //查找所有根邮件及其子邮件: 函数findRootAndChildMessagesmessages{ //1.将每个id链接到其各自的消息。id: 设ids={}; 对于Object.entriesmessages的let[id,message]{ ID[message.ID]=ID; } //2.将儿童与父母联系起来: 让孩子们={}; 对于Object.entriesmessages的let[id,message]{ 让parent_id=ids[message.IN_REPLY_TO]; 子项[父项id]=子项[父项id]| |[]; 子项[parent_id].pushid; } //3.将每个子级链接到其未定义的根: 让结果={}; 儿童中的儿童[未定义]{ 结果[儿童]=findAllChildrenchild,儿童; } 返回结果; } //例如: 让消息={ 1: { “ID”:“IDONE”, “IN_REPLY_TO”:未定义 }, 3: { “ID”:“IDTHREE”, '回复':'IDONE' }, 7: { 'ID':'IDSEVEN', '答复':'IDTHREE' }, 8: { 'ID':'IDEIGHT', '答复':'IDTHREE' } }
console.logfindroondchildmessages消息;顺便说一下,如果这是另一个问题的重复,请道歉。令人恼火的是,我不知道描述这些问题的大多数术语,这使得搜索这些问题变得很困难。不要道歉,封闭式问题有一个重要的目的——它们从特定的问题实例重定向到更抽象的解决方案。回答得很好!愚弄了我一会儿,它不工作,因为我重写了对象,使其尽可能简单。感谢您向我展示Object.entries,我以前从未见过它被使用过,我对将Object.keys与查找结合起来感到有点厌倦。谢谢!有时,看到不同风格的人实现相同的功能会令人振奋。如果您同意,那么codereview堆栈交换可能对您同样感兴趣。