[英]looping through an object (tree) recursively
有没有办法(在 jQuery 或 JavaScript 中)遍历每个 object 及其子孙等等?
如果是这样...我也可以读出他们的名字吗?
例子:
foo :{
bar:'',
child:{
grand:{
greatgrand: {
//and so on
}
}
}
}
所以循环应该做这样的事情......
loop start
if(nameof == 'child'){
//do something
}
if(nameof == 'bar'){
//do something
}
if(nameof =='grand'){
//do something
}
loop end
您正在寻找 for for...in
循环:
for (var key in foo)
{
if (key == "child")
// do something...
}
请注意, for...in
循环将遍历任何可枚举属性,包括添加到对象原型中的属性。 为了避免对这些属性进行操作,您可以使用hasOwnProperty
方法来检查该属性是否仅属于该对象:
for (var key in foo)
{
if (!foo.hasOwnProperty(key))
continue; // skip this property
if (key == "child")
// do something...
}
以递归方式执行循环可以像编写递归函数一样简单:
// This function handles arrays and objects
function eachRecursive(obj)
{
for (var k in obj)
{
if (typeof obj[k] == "object" && obj[k] !== null)
eachRecursive(obj[k]);
else
// do something...
}
}
你可以有一个递归函数,其中内置了一个解析函数。
function parseObjectProperties (obj, parse) {
for (var k in obj) {
if (typeof obj[k] === 'object' && obj[k] !== null) {
parseObjectProperties(obj[k], parse)
} else if (obj.hasOwnProperty(k)) {
parse(k, obj[k])
}
}
}
我使用 OP 的foo
对象,这里是它是如何工作的
var foo = { bar:'a', child:{ b: 'b', grand:{ greatgrand: { c:'c' } } } } // use this recursive function with a parse funciton function parseObjectProperties (obj, parse) { for (var k in obj) { if (typeof obj[k] === 'object' && obj[k] !== null) { parseObjectProperties(obj[k], parse) } else if (obj.hasOwnProperty(k)) { parse(k, obj[k]) } } } //*** // then apply to the property the task you want, in this case just console parseObjectProperties(foo, function(k, prop) { console.log(k + ': ' + prop) })
如果你想找回关系树,你可以递归地使用 Object.keys。
function paths(item) { function iter(r, p) { var keys = Object.keys(r); if (keys.length) { return keys.forEach(x => iter(r[x], p.concat(x))); } result.push(p); } var result = []; iter(item, []); return result; } var data = { foo: { bar: '', child: { grand: { greatgrand: {} } } } }; console.log(paths(data));
这可以扩展为在对象结构中搜索与函数匹配的值:
function objectSearch(rootItem, matcher) { const visited = []; const paths = []; function iterate(item, path) { if (visited.includes(item)) { return; } visited.push(item); if (typeof item === "object" && item !== null) { var keys = Object.keys(item); if (keys.length) { return keys.forEach(key => iterate(item[key], path.concat(key))); } } if (matcher(item)) { paths.push(path); } } iterate(rootItem, []); return paths; } function searchForNaNs(rootItem) { return objectSearch(rootItem, (v) => Object.is(NaN, v)); } var banana = { foo: { bar: "", child: { grand: { greatgrand: {}, nanan: "NaN", nan: NaN, }, }, }, }; console.log("There's a NaN at", searchForNaNs(banana)[0].join("."), "in this object:", banana);
考虑使用object-scan 。 一旦你把头环绕在它周围,它对于数据处理来说是强大的。
一件很棒的事情是这些项目以“删除安全”的顺序遍历。 所以如果你删除一个,它不会搞乱循环。 而且您可以访问许多其他属性,例如父母等。
// const objectScan = require('object-scan'); const obj = { foo: { bar: '', child: { grand: { greatgrand: { /* and so on */ } } } } }; objectScan(['**'], { filterFn: ({ property }) => { console.log(property); } })(obj); // => greatgrand // => grand // => child // => bar // => foo
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>
免责声明:我是对象扫描的作者
我建议使用sindresorhus的map-obj和filter-obj实用程序...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.