Reputation: 523
I have the following array
var array = [
{id:"1",subject:"CE1",mark:"20"},{id:"1",subject:"CE2",mark:"30"},
{id:"2",subject:"CE1",mark:"40"},{id:"3",subject:"CE1",mark:"20"},
{id:"3",subject:"CE2",mark:"20"},{id:"1",subject:"CE1",mark:"40"},
{id:"1",subject:"CE2",mark:"30"},{id:"2",subject:"CE1",mark:"20"},
{id:"3",subject:"CE1",mark:"10"},{id:"3",subject:"CE2",mark:"10"}
]
and I want the following array
var resultArray = [
{id:"1",subject:"CE1",mark:"60"},
{id:"1",subject:"CE2",mark:"60"},
{id:"2",subject:"CE1",mark:"40"},
{id:"3",subject:"CE1",mark:"30"},
{id:"3",subject:"CE2",mark:"30"}
]
I have the following code which group the array by id only.
var totalArray = Object.values(array .reduce((a, {id, subject, mark}) => {
let totMark= mark;
if(a.hasOwnProperty(id)) {
a[id].mark+= totMark;
} else {
a[id] = {
id:id,
subject:subject,
mark:totMark,
}
}
return a;
}, {}));
How can I group my array by two properties using javascript?
Upvotes: 1
Views: 1842
Reputation: 33
@adiga's answer will always add the first matching key twice. The first time a key comes up, we don't want to add it to itself!
This line
acc[key] = acc[key] || { id, subject, mark };
needs to be
acc[key] = acc[key] || { id, subject, mark: 0 };
Final snippet:
var array = [
{id:"1",subject:"CE1",mark:"20"},{id:"1",subject:"CE2",mark:"30"},
{id:"2",subject:"CE1",mark:"40"},{id:"3",subject:"CE1",mark:"20"},
{id:"3",subject:"CE2",mark:"20"},{id:"1",subject:"CE1",mark:"40"},
{id:"1",subject:"CE2",mark:"30"},{id:"2",subject:"CE1",mark:"20"},
{id:"3",subject:"CE1",mark:"10"},{id:"3",subject:"CE2",mark:"10"}
]
var totalArray = Object.values(array.reduce((acc, { id, subject, mark }) => {
mark = +mark; // convert to number
const key = id + '_' + subject; // unique combination of id and subject
acc[key] = acc[key] || { id, subject, mark: 0 };
acc[key].mark += mark;
return acc;
}, {}));
console.log(totalArray)
Upvotes: 2
Reputation: 35222
You need to follow a similar approach. Instead of adding id
as a key to the accumulator, you can create a new key which is a combination of the 2 keys you want to group with.
var array = [
{id:"1",subject:"CE1",mark:"20"},{id:"1",subject:"CE2",mark:"30"},
{id:"2",subject:"CE1",mark:"40"},{id:"3",subject:"CE1",mark:"20"},
{id:"3",subject:"CE2",mark:"20"},{id:"1",subject:"CE1",mark:"40"},
{id:"1",subject:"CE2",mark:"30"},{id:"2",subject:"CE1",mark:"20"},
{id:"3",subject:"CE1",mark:"10"},{id:"3",subject:"CE2",mark:"10"}
]
var totalArray = Object.values(array.reduce((acc, { id, subject, mark }) => {
mark = +mark; // convert to number
const key = id + '_' + subject; // unique combination of id and subject
acc[key] = acc[key] || { id, subject, mark };
acc[key].mark += mark;
return acc;
}, {}));
console.log(totalArray)
Upvotes: 1