【问题标题】:Find object by property key deep Javascript通过属性键深度 Javascript 查找对象
【发布时间】:2023-03-27 04:07:02
【问题描述】:

我有以下代码:

你可以去 jsbin 这里.. https://jsbin.com/wupukuhita/1/edit?js,console

var foundObjects = [];
var findObjectByLabel = function(obj, key) {

    var foundObject = [];    
    for(var i in obj) {
      if(typeof obj[i] === "object"){
        if(typeof obj[i][key] !== "undefined"){
            foundObjects.push(obj[i]);
        }
        findObjectByLabel(obj[i],key);
      }
    }
    return null;
};

我正在递归地遍历一个对象以找出某个属性是否存在。 然后如果确实存在,则返回父对象。

您可以查看 jsbin 链接以获取完整示例。

我不喜欢函数外的foundObjects。

我怎样才能把它放在函数中,然后从函数中返回包含某个属性的对象。

https://jsbin.com/wupukuhita/1/edit?js,console

【问题讨论】:

    标签: javascript recursion


    【解决方案1】:

    您可以使用 javascript 闭包,它基本上是另一个函数中的一个函数,第二个函数可以访问主函数对象
    在这里查看完整的代码,它和你的一样,除了我们返回数组

    var foundObjects = function (obj,key) {
        var foundObject = [];
        var findObjectByLabel = function(obj,key) {
            for (var i in obj) {
                if (typeof obj[i] === 'object') {
                    if (typeof obj[i][key] !== 'undefined') {
                        foundObject.push(obj[i]);
                    }
                    findObjectByLabel(obj[i], key);
                }
            }
            return null;
        };
        findObjectByLabel(obj,key);
        return foundObject ;
    }
    
    
    var mainObj = {
        name: 'MainForm', // main form
        type: 'Form',
        dirty: false,
        valid: true,
        Errors: [],
        formOrInputElements: [
            {
                name: 'Age', // normal input
                type: 'Text',
                value: '',
                dirty: true,
                valid1: true,
                test: {
                    name: 'test',
                    valid1: false,
                },
                Errors: [],
            },
            {
                name: 'CNP', // normal input
                type: 'Text',
                value: '',
                dirty: true,
                valid: true,
                Errors: [],
            },
        ],
    };
    
    let foundObject = foundObjects(mainObj, 'valid1');
    
    console.log(foundObject[0]);
    console.log(foundObject[1]);

    【讨论】:

    【解决方案2】:

    或者,您可以使用array#reduce 并遍历对象中的每个键值。如果是数组,递归调用函数 对于每个对象。如果是对象,请使用该对象调用函数。

    var mainObj = { name: "MainForm", type: "Form", dirty: false, valid: true, Errors: [], formOrInputElements: [ { name: "Age", type: "Text", value: "", dirty: true, valid1: true, test: { name: "test", valid1: false }, Errors: [] }, { name: "CNP", type:"Text", value: "", dirty: true, valid: true, Errors: [] } ] }
    
    var findObjectByLabel = function(obj, key) {
    
      return Object.keys(obj).reduce((r, k) => {
        if (k === key) {
          r.push(Object.assign({}, obj));
        } else if (Array.isArray(obj[k])) {
          obj[k].forEach(x => r = r.concat(findObjectByLabel(x, key)));
        } else if (typeof obj[k] === 'object') {
          r = r.concat(findObjectByLabel(obj[k], key));
        }
        return r;
      }, []);
    
    };
    
    console.log(findObjectByLabel(mainObj, "valid1"));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案3】:

      function findObjectByLabel(haystack, needle, buffer = []) {
          if (typeof haystack === 'object') {
              for (const prop in haystack) {
                  const result = prop === needle ? [haystack] : findObjectByLabel(haystack[prop], needle);
                  if (result.length > 0) {
                      buffer = buffer.concat(result);
                  }
              }
          }
          return buffer;
      }
      
      
      // Unit test
      function test_findObjectByLabel() {
          const obj = {
              foo: {
                  foo1: {
                      item1: 'item1',
                      item2: 'item2',
                      item3: 'item3',
                  },
                  foo2: {
                      item1: 'item1',
                      item2: 'item2',
                      item3: 'item3',
                      subFoo: {
                          item1: 'item1',
                          item2: 'item2',
                          needle: 'needle',
                      }
                  }
              },
              bar: {
                  bar1: {
                      item1: 'item1',
                      item2: 'item2',
                      item3: 'item3',
                  },
                  bar2: {
                      item1: 'item1',
                      item2: 'item2',
                      item3: 'item3',
                      needle: 'needle',
                  }
              },
          }
      
          const expected = [
              obj.foo.foo2.subFoo, // <-- contain "needle"
              obj.bar.bar2,        // <-- contain "needle"
          ];
          const actual = findObjectByLabel(obj, 'needle');
      
          if (JSON.stringify(actual) === JSON.stringify(expected)) {
              console.log('Pass');
              console.log('expected => ', JSON.stringify(expected, null, 4));
              console.log('actual   => ', JSON.stringify(actual, null, 4));
          } else {
              console.log('Fail');
      
              console.log('Actual')
              console.log(JSON.stringify(actual));
              console.log('is not equal to expected');
              console.log(JSON.stringify(expected));
          }
      }
      
      test_findObjectByLabel();

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-31
        • 2015-04-25
        • 1970-01-01
        • 2011-08-20
        • 2015-12-23
        • 2016-07-26
        • 2017-11-17
        • 1970-01-01
        相关资源
        最近更新 更多