Reputation: 2339
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
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
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
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