0

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;
                }
            }
        }
1
  • 1
    What really matters here is understanding the pattern of what you're looking for, then you can create an algorithm that works. I'm not easily seeing what the pattern is for the data you are collecting. If it's something that is specific and unique in each situation, it's going to be difficult to write an all-encompassing function to extract whatever data you need. Commented Mar 21, 2017 at 19:43

3 Answers 3

1

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));

Sign up to request clarification or add additional context in comments.

Comments

0

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;
}

Comments

0

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/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.