Please see my Fiddle which includes all the code that follows.
My apologies if this question has been answered before. I found similar questions on here about grouping by property, but I did not find an example where the result was still an array of objects.
I'm starting with this data format:
const originalData = [
{
"groupId": 0,
"color": "red",
"shape": "circle"
},
{
"groupId": 1,
"color": "green",
"shape": "square"
},
{
"groupId": 1,
"color": "orange",
"shape": "hexagon"
},
{
"groupId": 1,
"color": "purple",
"shape": "triangle"
},
{
"groupId": 2,
"color": "aqua",
"shape": "diamond"
},
{
"groupId": 2,
"color": "blue",
"shape": "trapezoid"
}
];
And I would like to transform it into a new array of objects, grouped by groupId
property value:
const desiredData = [
{
"groupId": 0,
"items": [
{
"color": "red",
"shape": "circle"
}
]
},
{
"groupId": 1,
"items": [
{
"color": "green",
"shape": "square"
},
{
"color": "orange",
"shape": "hexagon"
},
{
"color": "purple",
"shape": "triangle"
}
]
},
{
"groupId": 2,
"items": [
{
"color": "aqua",
"shape": "diamond"
},
{
"color": "blue",
"shape": "trapezoid"
}
]
}
];
This reduce function (which I found on MDN) is the closest I was able to come to transforming my data. My experience with transforming data in Javascript is limited, and I am not sure how to add fields (like group
) during the transformation process. Also, the result is an object, not an array of objects.
const actualFormattedData = originalData.reduce((acc, obj) => {
let key = obj['groupId'];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
Output from the reduce function:
{
"0": [
{
"groupId": 0,
"color": "red",
"shape": "circle"
}
],
"1": [
{
"groupId": 1,
"color": "green",
"shape": "square"
},
{
"groupId": 1,
"color": "orange",
"shape": "hexagon"
},
{
"groupId": 1,
"color": "purple",
"shape": "triangle"
}
],
"2": [
{
"groupId": 2,
"color": "aqua",
"shape": "diamond"
},
{
"groupId": 2,
"color": "blue",
"shape": "trapezoid"
}
]
}
The ultimate goal is to map the array of objects in React. I know I can use Object.entries
and array indices to achieve a similar result with actualFormattedData
as-is, but it would be ideal if I could first make actualFormattedData
look exactly like desiredData
.