我有一个类似下面的对象,我正在寻找一种方法来为树中的每个子对象添加一个属性。也就是说,我想为从0到n计数的对象添加一个数字。我知道我可以使用递归函数遍历对象,但由于范围可变,我无法使用简单的递增变量来计算我在树中的数量。
当前对象:
var tree = [
{
name: 'a',
children: []
},{
name: 'b',
children: [
{
name: 'c',
children: []
}
]
},
{
name: 'd',
children: [
{
name: 'e',
children: [
{
name: 'f',
children: []
},
{
name: 'g',
children: []
}
]
}
]
}
];
所需对象:
var tree = [
{
name: 'a',
number: 0,
children: []
},{
name: 'b',
number: 1,
children: [
{
name: 'c',
number: 2,
children: []
}
]
},
{
name: 'd',
number: 3,
children: [
{
name: 'e',
number: 4,
children: [
{
name: 'f',
number: 5,
children: []
},
{
name: 'g',
number: 6,
children: []
}
]
}
]
}
];
答案 0 :(得分:2)
使用计数器作用域引发的问题可以通过在闭包中定义计数器来解决,在闭包中也可以使用递归函数。
这是一个ES6函数:
function numberNodes(tree, n = 0) {
return (function recurse(children) {
return children.map( node => Object.assign({}, node, {
number: n++,
children: recurse(node.children)
}) );
})(tree);
}
// Sample data
var tree = [{ name: 'a', children: []},
{ name: 'b', children:
[{ name: 'c', children: []}]},
{ name: 'd', children:
[{ name: 'e', children:
[{ name: 'f', children: []}, { name: 'g', children: []}]}]}];
// Return tree with numbers added:
tree = numberNodes(tree);
// Output result
console.log(tree);
请注意,此函数不会改变您传递的树,只有返回值具有添加的属性。所以这是函数式编程的做法。
答案 1 :(得分:1)
您只需要在递归函数之外设置计数器变量,并在循环对象之前递增它。
var tree = [{"name":"a","children":[]},{"name":"b","children":[{"name":"c","children":[]}]},{"name":"d","children":[{"name":"e","children":[{"name":"f","children":[]},{"name":"g","children":[]}]}]}];
function addNumber(input) {
var counter = 0;
function rec(data) {
data.forEach(function(e) {
if (typeof e == 'object' && !Array.isArray(e)) {
e.number = counter++;
for (var p in e) {
if (typeof e[p] == 'object') rec(e[p])
}
}
})
}
rec(input)
}
addNumber(tree);
console.log(tree)