我正在尝试递归搜索包含字符串、数组和其他对象的对象,以在最深层次找到一个项目(匹配一个值),但是我总是得到 undefined 作为返回结果。我可以通过一些控制台日志看到我正在找到该项目,但它被覆盖了。知道我哪里出错了吗?
var theCobWeb = {
biggestWeb: {
item: "comb",
biggerWeb: {
items: ["glasses", "paperclip", "bubblegum"],
smallerWeb: {
item: "toothbrush",
tinyWeb: {
items: ["toenails", "lint", "wrapper", "homework"]
}
}
},
otherBigWeb: {
item: "headphones"
}
}
};
function findItem (item, obj) {
var foundItem;
for (var key in obj) {
if (obj[key] === item) {
foundItem = obj;
} else if (Array.isArray(obj[key]) && obj[key].includes(item)) {
foundItem = obj;
} else if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
findItem(item, obj[key]);
}
}
return foundItem;
}
var foundIt = findItem('glasses', theCobWeb);
console.log('The item is here: ' + foundIt); // The item is here: undefined
编辑:根据下面的反馈稍微清理了代码。
function findItem (item, obj) {
for (var key in obj) {
if (obj[key] === item) { // if the item is a property of the object
return obj; // return the object and stop further searching
} else if (Array.isArray(obj[key]) && obj[key].includes(item)) { // if the item is inside an array property of the object
return obj; // return the object and stop the search
} else if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { // if the property is another object
var res = findItem(item, obj[key]); // get the result of the search in that sub object
if(res) return res; // return the result if the search was successful, otherwise don't return and move on to the next property
}
}
return null; // return null or any default value you want if the search is unsuccessful (must be falsy to work)
}
注 1: Array.isArray
并且Array.prototype.includes
已经返回布尔值,因此无需根据布尔值检查它们。
注 2:您可以使用NOT 运算符( !
)翻转布尔值的值。
注意3:您必须在找到结果后立即返回结果(如果找到),这样您就不会浪费时间寻找已有的东西。
注意4:搜索的返回结果将是一个对象(如果找到)并且由于对象是通过引用而不是通过值传递的,更改该对象的属性也会更改原始对象的属性。
编辑:找到最深的对象:
如果要找到最深的对象,则必须遍历对象中的每个对象和子对象,obj
并且每次必须存储对象及其深度(如果结果的深度大于之前的结果)课程)。这是带有一些注释的代码(我使用了_find
实际上在所有对象上调用的内部函数):
function findItem (item, obj) {
var found = null; // the result (initialized to the default return value null)
var depth = -1; // the depth of the current found element (initialized to -1 so any found element could beat this one) (matched elements will not be assigned to found unless they are deeper than this depth)
function _find(obj, d) { // a function that take an object (obj) and on which depth it is (d)
for (var key in obj) { // for each ...
// first call _find on sub-objects (pass a depth of d + 1 as we are going to a one deep bellow)
if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
_find(obj[key], d + 1);
}
// then check if this object actually contain the item (we still at the depth d)
else if (obj[key] === item || (Array.isArray(obj[key]) && obj[key].includes(item))) {
// if we found something and the depth of this object is deeper than the previously found element
if(d > depth) {
depth = d; // then assign the new depth
found = obj; // and assign the new result
}
}
}
}
_find(obj, 0); // start the party by calling _find on the object obj passed to findItem with a depth of 0
// at this point found is either the initial value (null) means nothing is found or it is an object (the deepest one)
return found;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句