Reputation: 67
I have an array containing the following objects.
var notTotal = [{"Year":2012,"Value":800579},
{"Year":2012,"Value":654090},
{"Year":2012,"Value":758092},
{"Year":2013,"Value":343928},...More objects.. ]
What im trying to do is traverse this array of objects where only one Year exists instead of multiple and to add up the Values for that year. Using the example above..
var total = [{"Year":2012,"Value":2556689},
//Total of first three 2012 assuming there isnt anymore 2012 in the array
{"Year":2013,"Value":343928},...]
I have tried something like the following:
for(var i = 0; i < notTotal.length; i++) {
if (total.includes(notTotal[i].Year || notTotal[i])) {
//Add the value of the year in notTotal array to the same year in total array
} else {
total.push(notTotal[i]); //add year and value if it does not exist to the total array
}
}
Apologies if this is a duplicate. It seems like a pretty specific question.
Thanks!
Upvotes: 0
Views: 90
Reputation: 390
An easy solution would be to create an object, holding totals by year.
var totalByYear = {};
You can then loop over the array using notTotal.forEach
or a for
loop as you've shown, adding to the value of the relevant year inside the totalByYear
object.
notTotal.forEach(function(ele) { totalByYear[ele.Year] += ele.Value });
This yields an object with year keys and total values, e.g. using your example:
{'2012': 2556689, '2013': 343928 /* other years */}
The desired format (for D3
) can then be built from the totalByYear
object (and the totals by year printed):
var totals = [];
for (year in totalByYear) {
console.log('Total for year ' + year + ' is ' + totalByYear[year]);
//Build the correctly formatted array
totals.push({ Year: year, Value: totalByYear[year]});
}
//Prints:
//Total for year 2012 is 2556689
//etc.etc.
The totals
array will then have the desired format.
Upvotes: 2
Reputation:
one more solution :
function yearlyValueFilter(array){
var yearlyValue = {}
array.forEach( (obj) => { //litterate on the input
var year = obj.Year
var value = obj.Value
if((year in yearlyValue)){ //if the array with not duplicated years conatins the litteration year just plus that value
yearlyValue[year] += value
}else{ //if not conatins, it gets as a basic value
yearlyValue[year] = value
}
})
return yearlyValue
}
Upvotes: 1
Reputation: 214927
var notTotal = [{"Year":2012,"Value":800579},
{"Year":2012,"Value":654090},
{"Year":2012,"Value":758092},
{"Year":2013,"Value":343928}]
var totalObj = notTotal.reduce((sum, obj) => {
sum[obj.Year] = sum[obj.Year] + obj.Value || obj.Value;
return sum;
}, {});
// convert total to the format you need;
var total = Object.entries(totalObj).map(([Year, Value]) => ({Year, Value}))
console.log(total);
Upvotes: 1
Reputation: 386560
You could use a hash table and check if the year does not exist, then generate a new result set. Then update the total count.
var values = [{ Year: 2012, Value: 800579 }, { Year: 2012, Value: 654090 }, { Year: 2012, Value: 758092 }, { Year: 2013, Value: 343928 }],
hash = Object.create(null),
totals = [];
values.forEach(function (o) {
hash[o.Year] || totals.push(hash[o.Year] = { Year: o.Year, Value: 0 });
hash[o.Year].Value += o.Value;
});
console.log(totals);
Upvotes: 0
Reputation: 176
Great question! To explain what's happening in your if (total.includes(notTotal[i].Year || notTotal[i]))
is that you are looking through your total
array for either just the year, or just an existing notTotal[i]
exactly as it is. So your loop is trying to find a value that's exactly 2012
or exactly "Year":2012,"Value":2556689
. Ergo, if your total
array looked like this:
[{"Year":2012, "Value": 12345}]
your for loop would not find it even though there is an object with 2012
as its year. As for how to fix this, take a look at this previous question!
How to determine if Javascript array contains an object with an attribute that equals a given value?
Hopefully that helps :)
Upvotes: 1
Reputation: 138257
You could built a hash table:
var hash = {},total=[];
for(const {Year,Value} of notTotal){
if(hash[Year]){
hash[Year].Value+=Value;
}else{
total.push(hash[Year]={Year,Value});
}
}
Note: object properties are normally not capitalized...
Upvotes: 0