求和子级值并将结果保存到Javascript中n元树中的父级
我有一个Javascript树,其结构如下,这是一个简单的示例:求和子级值并将结果保存到Javascript中n元树中的父级,javascript,arrays,recursion,tree,Javascript,Arrays,Recursion,Tree,我有一个Javascript树,其结构如下,这是一个简单的示例: tree: [ { id: 'A' parents: [] children: ['B'] value: 1 }, { id: 'B' parents: ['A'] children: ['C', 'D'] value: 1 }, { id: 'C' parents: ['
tree: [
{
id: 'A'
parents: []
children: ['B']
value: 1
},
{
id: 'B'
parents: ['A']
children: ['C', 'D']
value: 1
},
{
id: 'C'
parents: ['B']
children: []
value: 1
},
{
id: 'D'
parents: ['B']
children: []
value: 1
}
]
A
|
B
/ \
C D
每个节点都可以有一个不固定数量的子节点,我使用父节点数组来了解树根(当父节点数组为空时)
我尝试做的是一个递归函数:子值的总和保存在父值中(覆盖该值)。如果只有一个子项,则子项值保存在父项中。因此,这些值累积到根
树的结构好吗?我怎样才能完成这个功能
谢谢
编辑:
预期结果:
tree: [
{
id: 'A'
parents: []
children: ['B']
value: 2
},
{
id: 'B'
parents: ['A']
children: ['C', 'D']
value: 2
},
{
id: 'C'
parents: ['B']
children: []
value: 1
},
{
id: 'D'
parents: ['B']
children: []
value: 1
}
]
tree: [
{
id: 'A'
parents: []
children: ['B','E']
value: 3
},
{
id: 'B'
parents: ['A']
children: ['C', 'D']
value: 2
},
{
id: 'C'
parents: ['B']
children: []
value: 1
},
{
id: 'D'
parents: ['B']
children: []
value: 1
},
{
id: 'E'
parents: ['A']
children: ['F']
value: 1
},
{
id: 'F'
parents: ['E']
children: []
value: 1
}
]
另一个例子:
A
/ \
B E
/ \ |
C D F
所有节点值均为1
预期结果:
tree: [
{
id: 'A'
parents: []
children: ['B']
value: 2
},
{
id: 'B'
parents: ['A']
children: ['C', 'D']
value: 2
},
{
id: 'C'
parents: ['B']
children: []
value: 1
},
{
id: 'D'
parents: ['B']
children: []
value: 1
}
]
tree: [
{
id: 'A'
parents: []
children: ['B','E']
value: 3
},
{
id: 'B'
parents: ['A']
children: ['C', 'D']
value: 2
},
{
id: 'C'
parents: ['B']
children: []
value: 1
},
{
id: 'D'
parents: ['B']
children: []
value: 1
},
{
id: 'E'
parents: ['A']
children: ['F']
value: 1
},
{
id: 'F'
parents: ['E']
children: []
value: 1
}
]
A值=B值+E值
B值=C值+D值
E值=F值。请注意,树结构与您的树结构不同,但如果需要,您也可以插入其他属性(例如id)
const tree = {
value: 1,
children: [{
value: 1,
children: [{
value: 1,
children: null
},
{
value: 1,
children: null
}]
}]
};
function sum(node) {
var childSum = 0;
if (!node.children) return node.value;
for (var i = 0; i < node.children.length; i++) {
childSum += sum(node.children[i]);
}
node.value = childSum;
return childSum;
}
sum(tree);
const树={
价值:1,
儿童:[{
价值:1,
儿童:[{
价值:1,
子项:空
},
{
价值:1,
子项:空
}]
}]
};
函数和(节点){
var-childSum=0;
如果(!node.children)返回node.value;
对于(var i=0;i
让树=[
{
id:'A',
家长:[],
儿童:['B'],
价值:1
},
{
id:'B',
家长:['A'],
儿童:['C','D'],
价值:1
},
{
id:'C',
家长:['B'],
儿童:[],
价值:1
},
{
id:'D',
家长:['B'],
儿童:[],
价值:1
}
];
让leafNodes=[];
函数ArrayToObject(数组,键域){
返回数组.reduce((对象,项)=>{
obj[项目[关键字段]]=项目;
如果(!item.children.length&&!leafNodes.includes(item[keyField]))leafNodes.push(item[keyField]);
返回obj;
}, {});
}
让treeObject=ArrayToObject(树的“id”);
addSumToParentNode(叶节点);
函数addSumToParentNode(子节点){
if(childNodes.length){
让parentNodes=[];
childNodes.map(child=>{
if(treeObject[child].parents.length){
让parent=treeObject[child]。父对象[0];
如果(!parentNodes.includes(parent))parentNodes.push(parent);
treeObject[parent].value+=treeObject[child].value;
}
});
addSumToParentNode(父节点);
}
}
log(Object.values(treeObject))代码>您可以将根元素的引用以及每个项存储在哈希表中,以便更快地访问。然后通过对子元素使用递归来迭代根元素以获得想要的和
这种方法只是更新给定的数组
函数更新(数组){
var root=[],
references=array.reduce((r,o)=>{
如果(!o.parents.length){
根推力(外径);
}
r[o.id]=o;
返回r;
},Object.create(null));
root.REDUCT(函数和,id){
var o=参考[id];
返回s+(o.value=o.children.reduce(和,0)| | o.value);
}, 0);
返回数组;
}
var data1=[{id:'A',父项:[],子项:['B'],值:1},{id:'B',父项:['A'],子项:['C','D'],值:1},{id:'C',父项:['B'],子项:[],值:1},{id:'D',父项:['B'],子项:['D',值:1},
数据2=[{id:'A',父项:[],子项:['B',E'],值:1},{id:'B',父项:['A'],子项:['C',D'],值:1},{id:'C',父项:['B'],子项:[],值:1},{id:'D',父项:['B'],子项:[],值:1},{id:'E',父项:['A'],子项:['F'],值:1},{id:'F'
日志(更新(数据1));
日志(更新(数据2))代码>
作为控制台包装{max height:100%!important;top:0;}
为什么要将节点存储在数组中?为什么不把它当作一棵真正的树来保存呢?至少让它们可以通过id寻址。树的数据来自用户制作的图形,因此此结构是根据这些数据构建的。它可以变成一个真正的树,这是我首先得到的。是的,为了让你的函数工作,你需要某种树结构,所以你可以显式地转换数据。数据排序好了吗,比如根优先?您需要树结构,而不是平面数组,还是要平面数组?数据没有排序,要知道根,我检查节点是否有父节点。平面数组不是必需的,结构可以是其他的。函数正是我需要的,但是结构很难获得,因为我从中获取节点的数据没有排序。谢谢你的回答。函数很好,但求和只用于累加值。如果累积值上升到父级,我们不关心父级的原始值,因此我们不使用它来求和。我不明白,请将想要的结果添加到问题中。完成。A值为2,因为B值是C值和D值之和。未使用原始B值。是否仅获取树叶的总和?@KonaKona,然后需要检查value对象并获取所有属性以进行总和。我建议你自己试试,如果不行,问一个新问题。在评论中,回答扩展/不同的问题不合适。