简体   繁体   中英

Get values for a matching key recursively from object

I have this json object

{
  "data": {
    "user": {
      "user_info": {
        "id": "AoGC2HQ9vedHmzcMX"
      },
      "product": [
        {
          "node": {
            "id": "NzcxNzU2ODU1ODM1",
            "feedback": {
              "raters": {
                "nodes": [
                  {
                    "id": "1",
                    "name": "Dan"
                  },
                  {
                    "id": "2",
                    "name": "Allen"
                  },
                  {
                    "id": "3",
                    "name": "Williams"
                  }
                ]
              },
              "commentors": {
                "nodes": [
                  {
                    "id": "001",
                    "name": "Kent"
                  },
                  {
                    "id": "002",
                    "name": "Jay"
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

So how do I make it to get values of id If the parent property matches the desired key name, In this example I want to get all id's from raters.nodes only.

so expected result is

[1,2,3]

I know can do obj.data.user.product[0].node.feedback.raters.nodes and loop through that, but that is not how I want and the object tree occasionally changes.

I have used this recursive function

const recursiveSearch = (obj, searchKey, results = []) => {
   const r = results;
   Object.keys(obj).forEach(key => {
      const value = obj[key];
      if(key === searchKey && typeof value !== 'object'){
         r.push(value);
      }else if(typeof value === 'object'){
         recursiveSearch(value, searchKey, r);
      }
   });
   return r;
};

//returns all id's

While it works, it returns all id values, so how do I improve it? If not, how do I make this possible?

I think you want to really do this in 2 steps,..

First make a function to get the root node your looking for, and then you can just use map like normal.

Below is an example.

 var data = JSON.parse("{\"data\":{\"user\":{\"user_info\":{\"id\":\"AoGC2HQ9vedHmzcMX\"},\"product\":[{\"node\":{\"id\":\"NzcxNzU2ODU1ODM1\",\"feedback\":{\"raters\":{\"nodes\":[{\"id\":\"1\",\"name\":\"Dan\"},{\"id\":\"2\",\"name\":\"Allen\"},{\"id\":\"3\",\"name\":\"Williams\"}]},\"commentors\":{\"nodes\":[{\"id\":\"001\",\"name\":\"Kent\"},{\"id\":\"002\",\"name\":\"Jay\"}]}}}}]}}}"); function getRoot(data, search) { function get(path, data) { for (const [k, v] of Object.entries(data)) { if (v instanceof Object) { const pp = `${path}.${k}`; if (pp.slice(-search.length) === search) { return v; } const r = get(`${path}.${k}`, v); if (r) return r; } } } return get('', data); } const r = getRoot(data, 'raters.nodes'); console.log(r && r.map(i => i.id));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM