0

So I have this array:

var period = [{"total":852, "date":"2016-03"}, {"total":963, "date":"2016-03"},{"total":789,"date":"2016-02"},{"total":456,"date":"2016-04"},{"total":123,"date":"2016-01"},{"total":723,"date":"2016-01"}];

I need to display "total" data grouped by month. Which means I have to sum "total" amount on months that are repeated on the array (2016-03, 2016-01). To find the solution I need to understand why this

for ( var i = 0; i < period.length; i++ ){
 if (periodB.indexOf(period[i].date) == -1){
     periodB.push(period[i].date);  
 }

Returns this:

  ["2016-03", "2016-02", "2016-04", "2016-01"]

While this:

for ( var i = 0; i < period.length; i++ ){
  if (periodB.indexOf(period[i].date) == -1){
  periodB.push({"date": period[i].date, "total": period[i].total});
  }
}

Is returning this:

  [{date: "2016-03",total: 1704}, {date: "2016-03", total: 1926}, {date:"2016-02", total: 1578},{date: "2016-04",total: 912}, {date: "2016-01",total: 246}, {date: "2016-01", total: 1446 }]

On the first case repeated "dates" are not being pushed on to periodB array, but then on the second case they are.

kikemx78
  • 13
  • 6
  • I think it's because the data is nested in your second example so `periodB.indexOf(period[i].date) == -1` is true because there are technically no duplicates at that level/layer of the array. This: `{"date": period[i].date, "total": period[i].total}` does not equal this `period[i].date` - rather, the first *contains* the second. – jDo Apr 19 '16 at 22:54
  • Hi jDo, and what do you think about periodB.indexOf({"date": period[i].date}) == -1 ?? This doesn't work either. I get same result. – kikemx78 Apr 19 '16 at 22:59
  • Objects can't be compared in that way. From [this](http://stackoverflow.com/questions/12604062/javascript-array-indexof-doesnt-search-objects) question: *"Note that by definition, two objects are never equal, even if they have exactly the same property names and values. objectA === objectB if and only if objectA and objectB reference the same object."* – jDo Apr 19 '16 at 23:06

1 Answers1

0

You can solve your task using temporary object and one forEach loop

var obj = {};

period.forEach(e => {
    var month = e.date.split('-')[1]
    obj[month] = obj[month] + e.total || e.total
});

Result will be an object with month as key and total sum as a value

{
    '03': 1815, 
    '02': 789,
    '04': 456,
    '01': 846
}

Working example:

var period = [{ "total": 852, "date": "2016-03" }, { "total": 963, "date": "2016-03" }, { "total": 789, "date": "2016-02" }, { "total": 456, "date": "2016-04" }, { "total": 123, "date": "2016-01" }, { "total": 723, "date": "2016-01" }];

var obj = {};

period.forEach(e => {
    var month = e.date.split('-')[1]
    obj[month] = obj[month] + e.total || e.total
});

document.write(JSON.stringify(obj, 0, 2));
isvforall
  • 8,768
  • 6
  • 35
  • 50