【问题标题】:javascript find by value deep in a nested object/arrayjavascript在嵌套对象/数组中按值查找
【发布时间】:2026-01-12 17:25:01
【问题描述】:

你好,我在函数中返回对象时遇到问题,假设我有一个对象:

var elements = [{
    "fields": null,
    "id_base": "nv_container",
    "icon": "layout",
    "name": "container",
    "is_container": true,
    "elements" : [
        //another elements set here
    ]
}, 
{
    "id_base": "novo_example_elementsec",
    "name": "hello",
    "icon": "edit",
    "view": {}
}];

我想要的是一个可以找到具有特定键和值的对象的函数(在纯 javascript 中),并且我创建了一个函数,但它只是不能正常工作? ,我的功能:

function findNested(obj, key, value) {
    //Early return
    if (obj[key] === value) {
        console.log( 'before return' ); //until here . its fine
        return obj; //not working
    } else {
        for (var i = 0, len = Object.keys(obj).length; i <= len; i++) {
            if (typeof obj[i] == 'object') {
                this.findNested(obj[i] , key, value);
            }
        }
    }
}

我只是看不出我做错了什么?

谢谢。

【问题讨论】:

    标签: javascript function return javascript-objects


    【解决方案1】:

    在进行递归调用后,您错过了返回。如果在递归后找到对象,您需要继续将该结果冒泡(通过返回它)。正如@scott-marcus 所指出的,您还应该使用i &lt; len(而不是i &lt;= len)。

    var elements = [{
        "fields": null,
        "id_base": "nv_container",
        "icon": "layout",
        "name": "container",
        "is_container": true,
        "elements": [
          //another elements set here
        ]
      },
      {
        "id_base": "novo_example_elementsec",
        "name": "hello",
        "icon": "edit",
        "view": {}
      }
    ];
    
    function findNested(obj, key, value) {
      // Base case
      if (obj[key] === value) {
        return obj;
      } else {
        for (var i = 0, len = Object.keys(obj).length; i < len; i++) {
          if (typeof obj[i] == 'object') {
            var found = this.findNested(obj[i], key, value);
            if (found) {
              // If the object was found in the recursive call, bubble it up.
              return found;
            }
          }
        }
      }
    }
    
    console.log(findNested(elements, "icon", "layout")); // returns object
    console.log(findNested(elements, "icon", "edit")); // returns object
    console.log(findNested(elements, "foo", "bar")); // returns undefined

    【讨论】:

    • 非常感谢@smarx,这就是我想要的,我找了6个小时的解决方案,再次感谢
    【解决方案2】:

    仅供未来的读者阅读。除了 @user94559 的回答。

    1. 更通用的方法是遍历键而不是索引,否则不会找到所有嵌套属性。
    2. 在进行递归调用之前检查obj[k]忽略空值

    var elements = [{
        "fields": null,
        "id_base": "nv_container",
        "icon": "layout",
        "name": "container",
        "is_container": true,
        "elements": [
          {"icon": "nested"}
        ]
      },
      {
        "id_base": "novo_example_elementsec",
        "name": "hello",
        "icon": "edit",
        "view": {}
      }
    ];
    
    function findNested(obj, key, value) {
    
      // Base case
      if (obj[key] === value) {
        return obj;
      } else {
        var keys = Object.keys(obj); // add this line to iterate over the keys
    
        for (var i = 0, len = keys.length; i < len; i++) {
          var k = keys[i]; // use this key for iteration, instead of index "i"
    
          // add "obj[k] &&" to ignore null values
          if (obj[k] && typeof obj[k] == 'object') {
            var found = findNested(obj[k], key, value);
            if (found) {
              // If the object was found in the recursive call, bubble it up.
              return found;
            }
          }
        }
      }
    }
    
    console.log(findNested(elements, "icon", "layout")); // returns object
    console.log(findNested(elements, "icon", "edit")); // returns object
    console.log(findNested(elements, "foo", "bar")); // returns undefined
    
    // this will work now
    console.log(findNested(elements, "icon", "nested")); // returns object

    【讨论】: