Home > front end >  Transform JSON array of similar elements into nested array using JavaScript
Transform JSON array of similar elements into nested array using JavaScript

Time:10-15

Say I have the following JSON array:

[
{
    "name": "x",
    "category": "y",
    "attributes": {
        "name": "a",
        "description": "b"
    }
},
{
    "name": "x",
    "category": "y",
    "attributes": {
        "name": "c",
        "description": "d"
    }
}
]

How can I combine the elements where each property is identical, but add the differing properties to a nested array:

[
{
    "name": "x",
    "category": "y",
    "attributes": [
     {
        "name": "a",
        "description": "b"
     },
     {
        "name": "c",
        "description": "d"
     }
  ]
}
]

To be more specific, any differing elements should be appended to the array— for example if the attribute with name "c" had description "b", I would still want the entire attribute appended to the "attributes" list.

I've been unable to find this problem on StackOverflow through extensive searching. I appreciate your help!

CodePudding user response:

The most straightforward way is to use the reduce function

const data = [
    {
        name: 'x',
        category: 'y',
        attributes: {
            name: 'a',
            description: 'b',
        },
    },
    {
        name: 'x',
        category: 'y',
        attributes: {
            name: 'c',
            description: 'd',
        },
    },
];

const answer = data.reduce((result, current) => {
    const findIndex = result.findIndex((item) => item.name === current.name);

    // if the name does not exist in the result, append it to the result array
    if (findIndex === -1) {
        return [
            ...result,
            {
                name: current.name,
                category: current.category,
                attributes: [current.attributes],
            },
        ];
    }

    return result.map((value, index) => {
        if (index === findIndex) {
            value.attributes.push(current.attributes);
        }
        return value;
    });
}, []);

console.log(answer);

CodePudding user response:

Reduce can do the job. Here's one way

const myJson = [{
    "name": "x",
    "category": "y",
    "attributes": {
      "name": "a",
      "description": "b"
    }
  },
  {
    "name": "x",
    "category": "y",
    "attributes": {
      "name": "c",
      "description": "d"
    }
  }
]

const result = Object.values(
  myJson.reduce((acc, {
    name,
    category,
    attributes
  }) => (((acc[`${name}_${category}`] ??= {
    name,
    category,
    attributes: []
  }).attributes.push(attributes)), acc), {})
);
console.log(result)

CodePudding user response:

//It's very simple and best for huge data
 var arr = [
       {
          "name": "x",
          "category": "y",
          "attributes": {
             "name": "a",
             "description": "b"
          }
       },
       {
          "name": "x",
          "category": "y",
          "attributes": {
             "name": "c",
             "description": "d"
          }
       }
    ];
    
    var newArr = [];
    var objKeyValue = {};
    arr.forEach(rec => {
       if (objKeyValue[rec.name   rec.category])
          objKeyValue[rec.name   rec.category].attributes.push(rec.attributes);
       else objKeyValue[rec.name   rec.category] = { name: rec.name, category: rec.category, attributes: [rec.attributes] };
    });
    console.log("Output", Object.values(objKeyValue));
  • Related