I'm looking for reduce elements of array to one object by same key (id).
I try to use Array.reduce
, but cannot reduce same id elements.
Actually I don't really full understand Array.reduce
's mechanism... :(
Can anybody help me?
const arr = [{id: 1, value: 1, key: 'email'}, {id: 1, value: 1, key: 'status'}, {id: 2, value: 2, key: 'email'}, {id: 2, value: 2, key: 'status'}];
// EXPECTED
const arr = [{id: 1, data: {'email': 1, 'status': 1}}, {id: 2, data: {'email': 2, 'status': 2}}];
// WHAT I DO
const result = arr.reduce((acc, cur)=>{
const {id, key, value} = cur;
acc.forEach(el => {
if (el.id === id) {
el.data[key] = value;
}
})
acc = [...acc, {'id': id, 'data': { [key]: value }}];
return acc
}, [])
// WHAT I GET
[
{ id: 1, data: { email: 1, status: 1 } },
{ id: 1, data: { status: 1 } },
{ id: 2, data: { email: 2, status: 2 } },
{ id: 2, data: { status: 2 } }
]
CodePudding user response:
You can use Array.prototype.reduce()
this way,
By group them by id
as an object and then use Object.values()
to get the array that you wanted:
const arr = [
{id: 1, value: 1, key: 'email'},
{id: 1, value: 1, key: 'status'},
{id: 2, value: 2, key: 'email'},
{id: 2, value: 2, key: 'status'}
];
const arr2 = [
{id: 1, data: {'email': 1, 'status': 1}},
{id: 2, data: {'email': 2, 'status': 2}}
];
const res = Object.values(arr.reduce((acc, curr) => {
if(!acc[curr.id]) {
acc[curr.id] = {
id: curr.id,
data: {
[curr.key]: curr.value
}
}
} else {
acc[curr.id].data = {
...acc[curr.id].data,
[curr.key]: curr.value
}
}
return acc;
}, {}));
console.log(res);
CodePudding user response:
Try this one
const arr = [{id: 1, value: 1, key: 'email'}, {id: 1, value: 1, key: 'status'}, {id: 2, value: 2, key: 'email'}, {id: 2, value: 2, key: 'status'}];
const result = arr.reduce((acc, {id, key, value}) => {
const entry = acc.find(i => i.id === id);
if (!entry) {
acc.push({
id, data: {
[key]: value
}
});
} else {
entry.data[key] = value;
}
return acc;
}, []);
console.log(result);