Javascript 对象递归以在最深层查找项目

菲尔

我正在尝试递归搜索包含字符串、数组和其他对象的对象,以在最深层次找到一个项目(匹配一个值),但是我总是得到 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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章