按属性键深度Javascript查找对象

时间:2017-12-26 16:08:53

标签: javascript recursion

我有以下代码:

你可以在这里去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

3 个答案:

答案 0 :(得分: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]);

答案 1 :(得分:0)

或者,您可以使用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; }

答案 2 :(得分:0)

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();