Learner
Learner

Reputation: 2339

Best way to parse the Json in javascript and get the key / value

I am trying to parse the below JSON (format), flatten it out and get the required key / value (output) as mentioned below. I am trying to figure out the best way to do that.

I need to get the displayName and its corresponding parent

For Ex: Features: taxoFeatures

Input:

 {
          "Shop": {
            "subFilter": [
              {
                "taxoFeatures": {
                  "displayName": "Features"
                }
              },
              {
                "color_base": {
                  "displayName": "Colour"
                }
              }
            ],
            "displayName": "Shopping"
          },
          "Support": {
            "subFilter": [
              {
                "contentType": {
                  "displayName": "Content"
                }
              }
            ],
            "displayName": "Support documents"
          }
        }

Expected output:

    {
        "Shopping": "Shop",
        "Features":"taxoFeatures",
        "Colour":"color_base",
        "Content":"contentType",
        "Support documents":"Support"
        }

I was thinking of looping through the JSON and find the key and add the corresponding key and displayName value (and then loop through each child array and store those values as well). Any other ideas?

     let customName = {};
    for (const key in filter) {
            if (filter.hasOwnProperty(key)) {
                const value = filter[key];
                 if (isNotEmpty(value.displayName)) {
                    customName[value.displayName] = key;
                }
            }
        }

Upvotes: 0

Views: 110

Answers (3)

Nelson Teixeira
Nelson Teixeira

Reputation: 6572

Here is another way to do it:

var data  = {
          "Shop": {
            "subFilter": [
              {
                "taxoFeatures": {
                  "displayName": "Features"
                }
              },
              {
                "color_base": {
                  "displayName": "Colour"
                }
              }
            ],
            "displayName": "Shopping"
          },
          "Support": {
            "subFilter": [
              {
                "contentType": {
                  "displayName": "Content"
                }
              }
            ],
            "displayName": "Support documents"
          }
        };
                    
var res = {};
function search(obj){
    for(item in obj) {
    	res[obj[item].displayName] = item;
        if (obj[item].subFilter) 
            obj[item].subFilter.forEach((subitem)=>search(subitem));
    }
}

search(data);
console.log(res);

JSFiddle: https://jsfiddle.net/7b6bcjfk/

Upvotes: 0

Maikal
Maikal

Reputation: 247

Well, basically yes. You need to loop it throught, but as u have same code you can make a recursion, something like this:

function doit (json) {
    let ret = {};
    Object.keys(json).forEach((key) => {
        const childs = (!!json[key].subFilter) ? json[key].subFilter.map(doit) : [];
        ret          = Object.assign(ret, { [json[key].displayName]: key }, ...childs);
    });
    return ret;
}

Upvotes: 0

trincot
trincot

Reputation: 350760

You could use this recursive function which builds up the result object using reduce and Object.assign:

function transform(filter) {
    return Object.keys(filter).reduce( (acc, key) => {
        const value = filter[key];
        if (Object(value) === value) { // it's an object
            if ('displayName' in value) {
                acc[value.displayName] = key;
            }
            Object.assign(acc, transform(value)); // recurse
        }
        return acc;
    }, {});
}

// Sample input
const filter = {
  "Shop": {
    "subFilter": [
      {
        "taxoFeatures": {
          "displayName": "Features"
        }
      },
      {
        "color_base": {
          "displayName": "Colour"
        }
      }
    ],
    "displayName": "Shopping"
  },
  "Support": {
    "subFilter": [
      {
        "contentType": {
          "displayName": "Content"
        }
      }
    ],
    "displayName": "Support documents"
  }
}

console.log(transform(filter));

Upvotes: 1

Related Questions