Reputation: 23
I have an array of objects that contains results of a poll, which looks (for example) like this:
[
{title: 'cat', optionid: 7, points: 1 },
{title: 'cat', optionid: 7, points: 3 },
{title: 'cat', optionid: 7, points: 1 },
{title: 'dog', optionid: 8, points: 3 },
{title: 'dog', optionid: 8, points: 2 },
{title: 'dog', optionid: 8, points: 3 },
{title: 'pig', optionid: 9, points: 2 },
{title: 'pig', optionid: 9, points: 1 },
{title: 'pig', optionid: 9, points: 1 }
]
Basically, I want to loop through and sum the points for each optionid/title. So cat = 5, dog = 8, and pig = 4. Is there any way to do this in JavaScript? All my attempts have failed so far. I'm self-taught and just a beginner, so the less complex the solution the better.
Upvotes: 2
Views: 3050
Reputation: 1747
I think using reduce
is the best way to go here. However it can be confusing for newbs like me. So here is a more straight forward approach. Hopefully this is a little easier to follow.
var animals = [{title: 'cat', optionid: 7, points: 1 },
{title: 'cat', optionid: 7, points: 3 },
{title: 'cat', optionid: 7, points: 1 },
{title: 'dog', optionid: 8, points: 3 },
{title: 'dog', optionid: 8, points: 2 },
{title: 'dog', optionid: 8, points: 3 },
{title: 'pig', optionid: 9, points: 2 },
{title: 'pig', optionid: 9, points: 1 },
{title: 'pig', optionid: 9, points: 1 }];
// create new object to store results in
newObj = {};
// loop through animal objects
animals.forEach(function(animal){
// check if animal type has already been added to newObj
if(!newObj[animal.title]){
// If it is the first time seeing this animal type
// we need to add title and points to prevent errors
newObj[animal.title] = {};
newObj[animal.title]['points'] = 0;
}
// add animal points to newObj for that animal type.
newObj[animal.title]['points'] += animal.points
})
console.log(newObj)
Upvotes: 2
Reputation: 5309
use reduce
let data = [
{ title: 'cat', optionid: 7, points: 1 },
{ title: 'cat', optionid: 7, points: 3 },
{ title: 'cat', optionid: 7, points: 1 },
{ title: 'dog', optionid: 8, points: 3 },
{ title: 'dog', optionid: 8, points: 2 },
{ title: 'dog', optionid: 8, points: 3 },
{ title: 'pig', optionid: 9, points: 2 },
{ title: 'pig', optionid: 9, points: 1 },
{ title: 'pig', optionid: 9, points: 1 }
];
let result = data.reduce((re, obj) => {
let index = re.map(o => o.optionid).indexOf(obj.optionid);
index > -1 ? re[index].points += obj.points : re.push(obj);
return re;
}, []);
console.log(result);
Upvotes: 1
Reputation: 31910
It is pretty easy with reduce
var arr = [{title: 'cat', optionid: 7, points: 1 },
{title: 'cat', optionid: 7, points: 3 },
{title: 'cat', optionid: 7, points: 1 },
{title: 'dog', optionid: 8, points: 3 },
{title: 'dog', optionid: 8, points: 2 },
{title: 'dog', optionid: 8, points: 3 },
{title: 'pig', optionid: 9, points: 2 },
{title: 'pig', optionid: 9, points: 1 },
{title: 'pig', optionid: 9, points: 1 }]
var result = arr.reduce(function(acc, v) {
acc[v.title] = (acc[v.title] || 0) + v.points
return acc
}, {})
console.log(result)
Upvotes: 0