检索属性'x'属性内所有对象的'y'使用递归
Retrieve property 'x' of all objects inside property 'y' with recursion
考虑以下示例:
<script>
var McDuffFamily = {
name: "Jack McDuff I",
children: [
{
name:"Jack McDuff II",
children: [
{
name:"Jack McDuff III",
children: [
{
name:"Jack McDuff IV"
},
{
name:"Jonh McDuff I",
children: [
{
name:"Jonh McDuff I",
children: []
}
]
}
]
},
{
name:"Shena McDuff"
}
]
},
{
name:"Poor bastard",
children: [
{
name:"Citzen I",
children: [
{
name:"Darth Vader"
}
]
},
{
name:"Citzen II",
children: []
}
]
}
]
};
</script>
有没有什么无痛的方法可以检索所有"Jack McDuff I"后代的名字?
不使用递归:
var tree =[McDuffFamily];
var kids = [];
for (i=0; i < tree.length; i++) {
tree[i] && tree.push.apply(tree, tree[i].childrens)
kids.push(tree[i]);
}
kids; // all children
奇怪部分的分解:
tree[i] && tree.push.apply(tree, tree[i].childrens);
tree[i] &&
用于短路评估,确保当我调用tree[i].children
时tree[i]
不为空
tree.push.apply(tree, tree[i].childrens);
使用apply,它允许我调用一个函数,在本例中为Array.push,它接受tree
上任意数量的参数。所以这条线基本上变成了tree.push(child0, child1, ... childn);
。
所以现在CCD_ 7已经增加了当前子代上的子代的数量。
最简单的解决方案是只使用一个基本的递归函数:
function traverse(parent, visit) {
var ii;
visit(parent.name);
for (ii = 0; ii < parent.children.length; ii += 1) {
traverse(parent.children[ii], visit);
}
}
其中,parent
的初始值是McDuffFamily
,visit
是一个函数,它在访问节点时执行您想执行的任何操作。
此函数将返回家谱中给定名称的所有后代:
function getDescendants(family, name)
{
var result = [];
var iterate = function(node, isDescendant)
{
if(isDescendant)
result.push(node.name);
else
isDescendant = (node.name == name);
for(var i=0; i<node.children.length; i++)
iterate(node.children[i], isDescendant);
};
iterate(family, false);
return result;
}
它将返回一个数组,该数组包含所有子体的名称。
附言:我写的是children
而不是childrens
,因为children
已经是复数了。
for(var names = [], i = 0, l = McDuffFamily.childrens.length; i < l; i++) {
names.push(McDuffFamily.childrens[i].name);
}
names; // ['Jack McDuff II', 'Poor bastard']
如果你正在使用一个允许[].reduce的环境(比如Node或MooTools(,你也可以这样做:
names = McDuffFamily.childrens.reduce(function(prev, curr) {
prev.push(curr.name);
}, []);
names; // ['Jack McDuff II', 'Poor bastard']
我认为[].reduce看起来更好,但它对更费力
相关文章:
- 数组在递归方法中设置为null
- 如何递归地计算它在对象中出现的目标键(属性)的数量
- 下划线/洛达什号中的快捷方式,用于(递归)设置对象的所有属性
- 递归单步执行 HTML DOM 并打印属性
- 递归 js v3 未捕获的类型错误:无法读取未定义的属性“配置”
- JSON 对象 - 递归更改所有子项的属性名称
- 访问一个函数“”的不同级别内的属性;原型;函数和递归函数
- 递归函数未捕获父DOM节点属性
- 根据属性名称递归搜索对象中的值
- 在递归聚合物组件中插入新子组件时,无法读取未定义的属性“concat”
- JavaScript中的递归嵌套属性创建
- 递归地检查原型上的属性,如果存在则从原型中删除
- 检索属性'x'属性内所有对象的'y'使用递归
- 递归地遍历对象以构建属性列表
- 如何在Javascript中使用递归函数时读取对象的属性
- 使用JavaScript是递归地从对象中删除属性和值的最快方法
- 递归添加对象属性
- 深度递归比较:对象和属性
- 递归列出JSON中的所有对象属性路径
- 如何递归地列出对象属性,并将它们全部列在'一层深'-对象中