Home > Enterprise >  Find all the key-value pair and returning the path where the pair is in deep nested objects in JS
Find all the key-value pair and returning the path where the pair is in deep nested objects in JS

Time:01-05

I am trying to create a function which must do the following:

  • takes a JavaScript object as first parameter

  • the object can have any structure and depth

  • takes a string containing a key as second parameter

  • returns a map with all values that are found for that key within the object o the key in the resulting map shall be the path to the key within the object where "/" is used as separator o the root key for the map is the name of the object

the result has to be something like:

let obj = {
    id: 1,
    b: "value",
    c: 404,
    d: { 
        id: "value", 
        b: { 
            id: 1, 
            b: 2 
        } 
    },
};

myFunction(obj, 'id')
// [ ["" -> 1] ["d" -> "value"] ["d/b" -> 1] ]

I am doing the following:

let **findAllByKey** = (obj, keyToFind) =>
  Object.entries(obj).reduce(
    (acc, [key, value]) =>
      key === keyToFind
        ? acc.concat(value)
        : typeof value === "object"
        ? acc.concat(findAllByKey(value, keyToFind))
        : acc,
    []
  );


console.log(findAllByKey(obj, "id"));

But this only returns the values, and I am having trouble to get the path: "/d/b", and it says It must be done with a map constructor ( New Map() ), but with map, I have no clue how to do it.

CodePudding user response:

You could get the entries and iterate by checking the values.

const
    getPathes = (object, key) => Object
        .entries(object)
        .reduce((r, [k, v]) => {
            if (!v || typeof v !== 'object') return r;
            r.push(...getPathes(v, key).map(([l, v]) => [k   (l && '/')   l, v]));
            return r;
        }, key in object ? [['', object[key]]] : []),
    object = { id: 1, b: "value", c: 404, d: { id: "value", b: { id: 1, b: 2 } } };

console.log(getPathes(object, 'id')); // [["", 1], ["d", "value"], ["d/b" , 1]]

CodePudding user response:

You can use jsonpath library.

Sample:

const jp = require('jsonpath');
const result = jp.nodes(obj, '$..id');

Result:

[
  { path: [ '$', 'id' ], value: 1 },
  { path: [ '$', 'd', 'id' ], value: 'value' },
  { path: [ '$', 'd', 'b', 'id' ], value: 1 }
]

After that you get objects with path and value properties and can transform result as you want.

  •  Tags:  
  • Related