I have an array returning like so:
errors = [
{
"row": 1,
"key": "volume",
"errorType": "Data type",
"expectedType": "number",
"receivedType": "string"
},
{
"row": 1,
"key": "units",
"errorType": "Required data",
"expectedType": "string"
},
{
"row": 3,
"key": "year",
"errorType": "Incorrect data type",
"expectedType": "number",
"receivedType": "string"
},
{
"row": 3,
"key": "make",
"errorType": "Required data",
"expectedType": "string"
}
]
I would like to return an array of objects as below:
const errorGrouped = [
{
row:1,
data:[
{
"key":"volume",
"errorType": "Data type",
"expectedType": "number",
"receivedType": "string"
},
{
"key": "units",
"errorType": "Required data",
"expectedType": "string"
}
]
},
{
row:3,
data:[
{
"key": "year",
"errorType": "Incorrect data type",
"expectedType": "number",
"receivedType": "string"
},
{
"key": "make",
"errorType": "Required data",
"expectedType": "string"
}
]
}
]
I have had a go mapping through each object, destructuring into my required form of [{row:.., data:[...]}] but then I can't see an obvious and clean way to group - which suggests to me there's a better way to do this.
But yes, appreciate any help people can provide. Thanks
CodePudding user response:
You can use reduce method in JS.
const errorGrouped = errors.reduce((accumulatorList, error) => {
const group = accumulatorList.find(g => g.row === error.row);
if (group) {
// if the row is already there
group.data.push(error);
} else {
// if this is a new row
accumulatorList.push({ row: error.row, data: [error] });
}
// remove row attribute from the error object
delete error.row;
return accumulatorList;
}, []);
console.log(errorGrouped);
CodePudding user response:
You can achieve this in a single loop by using hash (JS Object)
- Hash will store the row index in the array so that you need not to look up again
- once you have the index then you just need to access that array position to push the data
const errors = [
{
"row": 1,
"key": "volume",
"errorType": "Data type",
"expectedType": "number",
"receivedType": "string"
},
{
"row": 1,
"key": "units",
"errorType": "Required data",
"expectedType": "string"
},
{
"row": 3,
"key": "year",
"errorType": "Incorrect data type",
"expectedType": "number",
"receivedType": "string"
},
{
"row": 3,
"key": "make",
"errorType": "Required data",
"expectedType": "string"
}
];
const rowMapIndex = {};
const output = [];
for (let rowObj of errors) {
const { row: rowID, ...restObj } = rowObj;
let addAt = output.length;
if (rowID in rowMapIndex) {
addAt = rowMapIndex[rowID];
} else {
rowMapIndex[rowID] = output.length;
output.push({ row: rowID, data: [] });
}
output[addAt].data.push(restObj)
};
console.log(output);