How to get the path from javascript object from key and value

I have a javascript object width depth.

I need to know the exact path from this key within the object ex: “obj1.obj2.data1”

I already know the key is data1, the value is 123.

My javascript object look like this

{
    obj1: {
        obj2: {
            data1: 213,
            data2: "1231",
            obj3: {
                data: "milf"
            }
        }
    },
    obj4: {
        description: "toto"
    }
}

How could I achieve that ?

here is a jsfiddle : http://jsfiddle.net/3hvav8xf/8/
I am trying to implement getPath.

5 thoughts on “How to get the path from javascript object from key and value”

  1. Here you go!

    function getPath(obj, value, path) {
    
        if(typeof obj !== 'object') {
            return;
        }
    
        for(var key in obj) {
            if(obj.hasOwnProperty(key)) {
                console.log(key);
                var t = path;
                var v = obj[key];
                if(!path) {
                    path = key;
                }
                else {
                    path = path + '.' + key;
                }
                if(v === value) {
                    return path;
                }
                else if(typeof v !== 'object'){
                    path = t;
                }
                var res = getPath(v, value, path);
                if(res) {
                    return res;
                } 
            }
        }
    
    }
    
    getPath(yourObject, valueYouWantToFindPath);
    

    Rerutns path if found, else returns undefined.
    I have only tested it with objects & comparison is very strict(ie: used ===).

    Update:
    Updated version that takes key as an argument.

    function getPath(obj, key, value, path) {
    
        if(typeof obj !== 'object') {
            return;
        }
    
        for(var k in obj) {
            if(obj.hasOwnProperty(k)) {
                console.log(k);
                var t = path;
                var v = obj[k];
                if(!path) {
                    path = k;
                }
                else {
                    path = path + '.' + k;
                }
                if(v === value) {
                    if(key === k) {
                        return path;
                    }
                    else {
                        path = t;
                    }
                }
                else if(typeof v !== 'object'){
                    path = t;
                }
                var res = getPath(v, key, value, path);
                if(res) {
                    return res;
                } 
            }
        }
    
    }
    
    getPath(yourObject, key, valueYouWantToFindPath);
    
    Reply
  2. I think recursive function can help to you (Updated version, to check value)

    function path(c, name, v, currentPath, t){
        var currentPath = currentPath || "root";
    
        for(var i in c){
          if(i == name && c[i] == v){
            t = currentPath;
          }
          else if(typeof c[i] == "object"){
            return path(c[i], name, v, currentPath + "." + i);
          }
        }
    
        return t + "." + name;
    };
    
    console.log(path({1: 2, s: 5, 2: {3: {2: {s: 1, p: 2}}}}, "s", 1));
    Reply
  3. JSON Object can be handled in JavaScript as associative array.

    So You can cycle through and store indexes of "parents" in some variables.

    Assume the whole object to be stored in variable called obj.

    for( var p1 in obj )

    {

       for( var p2 in obj[ p1 ] )
       {
           for( var p3 in obj[ p1 ][ p2 ] )
           {
               // obj[ p1 ][ p2 ][ p3 ] is current node
               // so for Your example it is obj.obj1.obj2.data1
           }
       }
    

    }

    Hope answer was helpful.

    Reply
  4. The following finds the path in any level of nested objects. Also with arrays.
    It returns all the paths found, which is something you want if you have keys with the same name.

    I like this approach because it works with lodash methods get and set out-of-the-box.

    function findPathsToKey(options) {
      let results = [];
    
      (function findKey({
        key,
        obj,
        pathToKey,
      }) {
        const oldPath = `${pathToKey ? pathToKey + "." : ""}`;
        if (obj.hasOwnProperty(key)) {
          results.push(`${oldPath}${key}`);
          return;
        }
    
        if (obj !== null && typeof obj === "object" && !Array.isArray(obj)) {
          for (const k in obj) {
            if (obj.hasOwnProperty(k)) {
              if (Array.isArray(obj[k])) {
                for (let j = 0; j < obj[k].length; j++) {
                  findKey({
                    obj: obj[k][j],
                    key,
                    pathToKey: `${oldPath}${k}[${j}]`,
                  });
                }
              }
    
              if (obj[k] !== null && typeof obj[k] === "object") {
                findKey({
                  obj: obj[k],
                  key,
                  pathToKey: `${oldPath}${k}`,
                });
              }
            }
          }
        }
      })(options);
    
      return results;
    }
    
    findPathsToKey({ obj: objWithDuplicates, key: "d" })
    // ["parentKey.arr[0].c.d", "parentKey.arr[1].c.d", "parentKey.arr[2].c.d"]
    

    Try it here – https://jsfiddle.net/spuhb8v7/1/

    If you want the result to be a single key (first encountered), you can change the results to be a string and if defined, then return the function with it.

    Reply
  5. I ended up with the following function, that works with nested objects/arrays :

    function findPath (obj, name, val, currentPath) {
      currentPath = currentPath || ''
    
      let matchingPath
    
      if (!obj || typeof obj !== 'object') return
    
      if (obj[name] === val) return `${currentPath}['${name}']`
    
      for (const key of Object.keys(obj)) {
        if (key === name && obj[key] === val) {
          matchingPath = currentPath
        } else {
          matchingPath = findPath(obj[key], name, val, `${currentPath}['${key}']`)
        }
    
        if (matchingPath) break
      }
    
      return matchingPath
    }
    
    const treeData = [{
      id: 1,
      children: [{
        id: 2
      }]
    }, {
      id: 3,
      children: [{
        id: 4,
        children: [{
          id: 5
        }]
      }]
    }]
    
    console.log(findPath (treeData, 'id', 5))
    Reply

Leave a Comment