Iterate till the end of the nested objects in javascript

I have a nested object like this :

let obj = {
_id: {},
person: {
    $search: {
        lname: true
    },
    _id: {},
    fname: {},
    something:{
        $search: {
            fname: true
        },
    }
},
code: {},
$search: {
    mname: true
},
vnvEmpName: {}
}

I have to retrieve all the keys inside the $search key, even if the object contains multiple occurences of $search it should return all the keys inside it which is :

lname 
fname
mname

I tried this :

function search(obj, id) {
var result = "";
// iterate the object using for..in

    for (var keys in obj) {
        // check if the object has any property by that name
        if (obj.hasOwnProperty(keys) && typeof obj[keys] === 'object') {
            // if the key is not undefined get it's value
            if (obj[keys][id] !== undefined) {
                result = (obj[keys][id])
            } else {
                // else again call the same function using the new obj value
                console.log("reahced")
                search(obj[keys], id)
            }
        }

    }
    return result;

}
console.log(search(obj, '$search'))

But I am getting only the key(lname) which is under the first instance of the $search. Please help me out to iterate it till the end.

3 thoughts on “Iterate till the end of the nested objects in javascript”

  1. You could check if the key is $search and take that nested key or check the nested objects.

    function getSearch(object, key) {
        return Object.entries(object).reduce((r, [k, v]) => r.concat(
            k === key
                ? Object.keys(v)[0]
                : v && typeof v === 'object'
                    ? getSearch(v, key)
                    : []
        ), []);
    }
    
    var object = { _id: {}, person: { $search: { lname: true }, _id: {}, fname: {}, something: { $search: { fname: true } } }, code: {}, $search: { mname: true }, vnvEmpName: {} };
    
    console.log(getSearch(object, '$search'));
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Reply
  2. You can create an iterator function using generators and then use it for your purpose. Here is an example code:

    let obj = { _id: {}, person: { $search: { lname: true }, _id: {}, fname: {}, something: { $search: { fname: true } } }, code: {}, $search: { mname: true }, vnvEmpName: {} };
    //iterator function 
    function* iterate(obj, stack='') {
        for (let property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                    yield *iterate(obj[property], stack + '.' + property);
                } else {
                    yield [stack, property, obj[property]];
                }
            }
        }
    }
    //using iterator function for searching
    let searchkey = "$search"
    for (let value of iterate(obj)) { 
        if(value[0].indexOf(searchkey) !== -1)
            console.log(value); 
    }

    I hope it helps.

    Reply
  3. You can try this

    let obj = {
    _id: {},
    person: {
        $search : {
            lname: true
        },
        _id: {},
        fname: 'test',
        something:{
            $search: {
                fname: true
            },
        }
    },
    code: {},
    $search: {
        mname: true
    },
    vnvEmpName: {}
    }
    var result;
    function search(obj, id) {
    
    // iterate the object using for..in
         for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
               if (obj[key][id] !== undefined) {
                    result = (obj[key][id]);
                     return result;
                } else {
                    // else again call the same function using the new obj value
                    console.log("reahced")
                    search(obj[key], id)
                }
            }
        }
        return result;
    }
    console.log(search(obj, 'lname'))
    Reply

Leave a Comment