通过嵌套的JavaScript对象迭代

我试图遍历一个嵌套的对象来检索一个string标识的特定对象。 在下面的示例对象中,标识符string是“label”属性。 我无法围绕如何遍历树来返回适当的对象。 任何帮助或build议将不胜感激。

var cars = { label: 'Autos', subs: [ { label: 'SUVs', subs: [] }, { label: 'Trucks', subs: [ { label: '2 Wheel Drive', subs: [] }, { label: '4 Wheel Drive', subs: [ { label: 'Ford', subs: [] }, { label: 'Chevrolet', subs: [] } ] } ] }, { label: 'Sedan', subs: [] } ] } 

你可以像这样创build一个recursion函数来对cars对象进行深度优先遍历。

 var findObjectByLabel = function(obj, label) { if(obj.label === label) { return obj; } for(var i in obj) { if(obj.hasOwnProperty(i)){ var foundLabel = findObjectByLabel(obj[i], label); if(foundLabel) { return foundLabel; } } } return null; }; 

这可以这样调用

 findObjectByLabel(car, "Chevrolet"); 

下面的代码假设没有循环引用,并假设subs总是一个数组(并且在叶节点中不为null):

 function find(haystack, needle) { if (haystack.label === needle) return haystack; for (var i = 0; i < haystack.subs.length; i ++) { var result = find(haystack.subs[i], needle); if (result) return result; } return null; } 

为了提高进一步树操作的性能,可以将树视图转换为线集合视图,如[obj1,obj2,obj3]。 您可以存储父子对象关系,以轻松导航到父/子范围。

在集合中search元素更有效,然后在树中查找元素(recursion,添加dynamic函数创build,闭包)。

Peter Olson的回答修改: https : //stackoverflow.com/a/8085118

  1. 可以避免string值!obj || (typeof obj === 'string' !obj || (typeof obj === 'string'
  2. 可以自定义你的密钥

 var findObjectByKeyVal= function (obj, key, val) { if (!obj || (typeof obj === 'string')) { return null } if (obj[key] === val) { return obj } for (var i in obj) { if (obj.hasOwnProperty(i)) { var found = findObjectByKeyVal(obj[i], key, val) if (found) { return found } } } return null } 

这是一个简单的方法,只使用3个variables而不recursion。

 function forEachNested(O, f){ O = Object.values(O); var cur; while (O.length){ cur = O.pop() f(cur); if (typeof cur === 'object' && cur.constructor === Object) O.push.apply(O, Object.values(cur)); } } 

如果循环引用有问题(例如,对象A的值是对象A本身,比如对象A包含自身),或者您只需要这些键,则可以使用以下较慢的解决scheme。

 function forEachNested(O, f){ O = Object.entries(O); var cur; function applyToEach(x){return cur[1][x[0]] === x[1]} while (O.length){ cur = O.pop(); f(cur[0], cur[1]); if (typeof cur[1] === 'object' && cur[1].constructor === Object && !O.some(applyToEach)) O.push.apply(O, Object.entries(cur[1])); } } 

由于这些方法不使用任何types的recursion,所以这些函数非常适合您可能具有数千个深度级别的区域。

尝试这样的事情:

 cars.subs[0].subs[0].label 

如果你想实际迭代,你可以在recursion函数中的每个对象上执行一个for循环,并在每次点击该对象的“subs”属性时调用该recursion函数。 这可能会导致问题,虽然如果你有一个非常深刻的对象结构