Search code examples
javascriptjquerylodash

Find property by name in a deep object


I have a HUGE collection and I am looking for a property by key someplace inside the collection. What is a reliable way to get a list of references or full paths to all objects containing that key/index? I use jQuery and lodash if it helps and you can forget about infinite pointer recursion, this is a pure JSON response.

fn({ 'a': 1, 'b': 2, 'c': {'d':{'e':7}}}, "d"); 
// [o.c]

fn({ 'a': 1, 'b': 2, 'c': {'d':{'e':7}}}, "e");
// [o.c.d]

fn({ 'aa': 1, 'bb': 2, 'cc': {'d':{'x':9}}, dd:{'d':{'y':9}}}, 'd');
// [o.cc,o.cc.dd]

fwiw lodash has a _.find function that will find nested objects that are two nests deep, but it seems to fail after that. (e.g. http://codepen.io/anon/pen/bnqyh)


Solution

  • This should do it:

    function fn(obj, key) {
        if (_.has(obj, key)) // or just (key in obj)
            return [obj];
        // elegant:
        return _.flatten(_.map(obj, function(v) {
            return typeof v == "object" ? fn(v, key) : [];
        }), true);
    
        // or efficient:
        var res = [];
        _.forEach(obj, function(v) {
            if (typeof v == "object" && (v = fn(v, key)).length)
                res.push.apply(res, v);
        });
        return res;
    }