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