Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript - Find path to object reference in nested object

Tags:

javascript

How can i recursively search a nested object to find the PATH to an object reference I'm providing?

My original object looks like:

a = {
 b: [
  { children: [...more objects] },
  { children: [] }
  etc..
 ],
 c: [
  { children: [...more objects] },
  { children: [] }
  etc..
 ]
}

I would like to call a function findDeepAndStorePath(a, obj) which would find the object reference and store the path to it in an array of indexes such as: ['b', 0, 1, 2].

like image 902
Dragos Ionescu Avatar asked Dec 18 '22 07:12

Dragos Ionescu


2 Answers

function findPath(a, obj) {
    for(var key in obj) {                                         // for each key in the object obj
        if(obj.hasOwnProperty(key)) {                             // if it's an owned key
            if(a === obj[key]) return key;                        // if the item beign searched is at this key then return this key as the path
            else if(obj[key] && typeof obj[key] === "object") {   // otherwise if the item at this key is also an object
                var path = findPath(a, obj[key]);                 // search for the item a in that object
                if(path) return key + "." + path;                 // if found then the path is this key followed by the result of the search
            }
        }
    }
}

var obj = {
  "a": [1, 2, {"o": 5}, 7],
  "b": [0, [{"bb": [0, "str"]}]]
};

console.log(findPath(5, obj));
console.log(findPath("str", obj).split("."));                     // if you want to get the path as an array you can simply split the result of findPath
like image 161
ibrahim mahrir Avatar answered Dec 24 '22 01:12

ibrahim mahrir


You could use Object.keys and check the values. If found, then the actual path is returned and the iteration stops. If not, all possible pathes are checked.

This proposal respects numeric keys off arrays.

function findPath(a, obj) {
    function iter(o, p) {
        return Object.keys(o).some(function (k) {
            result = p.concat(Array.isArray(o) ? +k : k);
            return o[k] === a || o[k] && typeof o[k] === 'object' && iter(o[k], result);
        });
    }
    var result;
    return iter(obj, []) && result || undefined;
}

var obj = { a: [1, 2, { o: 5 }, 7], b: [0, [{ bb: [0, "str"] }]] };

console.log(findPath(5, obj));     // ["a", 2, "o"]
console.log(findPath("str", obj)); // ["b", 1, 0, "bb", 1]
console.log(findPath(42, obj));    // undefined
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 36
Nina Scholz Avatar answered Dec 24 '22 00:12

Nina Scholz