0

I have an array of objects with number values that I am trying to loop over to get a result of and ARRAY of ARRAYS. Ive found examples of using for loop where the output is an ARRAY of OBJECTS. But I am having trouble looping over and adding the number values to create an array for each month value with the second value being a total of all the values listed for that month.

var input = [
  {month: "Jan", value: 3},
  {month: "Jan", value: 3.5},
  {month: "Feb", value: 2.1},
  {month: "Mar", value: 6},
  {month: "Apr", value: 4.3},
  {month: "May", value: 5.5},
  {month: "Jun", value: 7},
  {month: "Jun", value: 9},
  {month: "Jul", value: 7},
  {month: "Jul", value: 9},
  {month: "Jul", value: 7},
  {month: "Aug", value: 9},
  {month: "Sep", value: 9},
  {month: "Sep", value: 9},
  {month: "Oct", value: 8},
  {month: "Oct", value: 5},
  {month: "Oct", value: 3},
  {month: "Nov", value: 12},
  {month: "Nov", value: 19.5},
];

var result = [];

for (var i = 0; i < input.length; i++) {
  var data = input[i];
  var found = false;
  console.log(result[1][1], "help");
  for (var j = 0; j < result.length; j++) {
    if (result[j].month === data.month) {
      found = true;

      result[j][1] += data.value;
      break;
    }
  }
  if (!found) {
    result.push([data.month, data.value]);
  }
}

Currently returns an array of arrays but it is not adding the values instead it is making an array for each object.

My expected output would be:

[["Jan", 6.5],["Feb", 2.1],["Mar", 6],["Jun", 16]...etc]
CourtneyJ
  • 458
  • 6
  • 19
  • 2
    Does this answer your question? [Sum of array object property values in new array of objects in Javascript](https://stackoverflow.com/questions/37481539/sum-of-array-object-property-values-in-new-array-of-objects-in-javascript) – Heretic Monkey Aug 18 '22 at 18:53
  • The only thing that was wrong with your code was the `result[j].month` in your if statement... As given in the comment in my answer, result[j] is an array... arrays don't have a `.month` attribute by default. So your if statement was never being hit, so your `found` variable was always false, thus pushing all the data into the result array, instead of adding it when appropriate. – Shmack Aug 18 '22 at 19:57

4 Answers4

1

An alternate approach using month as keys in an Object.

var input = [
  { month: "Jan", value: 3 },
  { month: "Jan", value: 3.5 },
  { month: "Feb", value: 2.1 },
  { month: "Mar", value: 6 },
  { month: "Apr", value: 4.3 },
  { month: "May", value: 5.5 },
  { month: "Jun", value: 7 },
  { month: "Jun", value: 9 },
  { month: "Jul", value: 7 },
  { month: "Jul", value: 9 },
  { month: "Jul", value: 7 },
  { month: "Aug", value: 9 },
  { month: "Sep", value: 9 },
  { month: "Sep", value: 9 },
  { month: "Oct", value: 8 },
  { month: "Oct", value: 5 },
  { month: "Oct", value: 3 },
  { month: "Nov", value: 12 },
  { month: "Nov", value: 19.5 },
];

const totalMonthObj = {};
for (monthObj of input) {
  if (totalMonthObj[monthObj.month]) {
    totalMonthObj[monthObj.month].value += monthObj.value;
  } else {
    totalMonthObj[monthObj.month] = monthObj;
  }
}
console.log(Object.values(totalMonthObj).map(({month,value})=>[month,value]));
Shub
  • 2,686
  • 17
  • 26
0

You can use array.reduce:

const result = input.reduce((r, item) => {
  const { month, value } = item;
  const existing = r.find((x) => x[0] === month);
  if (existing) {
    existing[1] += value;
  } else {
    r.push([month, value]);
  }
  return r;
}, []);

Output:

console.log(JSON.stringify(result));

[["Jan",6.5],["Feb",2.1],["Mar",6],["Apr",4.3],["May",5.5],["Jun",16],["Jul",23],["Aug",9],["Sep",18],["Oct",16],["Nov",31.5]] 

Sergey Sosunov
  • 4,124
  • 2
  • 11
  • 15
0

just pass the months array to the function and it will return your expectation

function filterMonth(arr){

    let data = [];
    
    for (let index = 0; index < arr.length; index++) {
        let findIndex = data.findIndex(item => item[0] === arr[index].month)

        if (findIndex === -1){
            data.push([arr[index].month,arr[index].value])
        }
    }

    return data
}

NOTE** this function will only work if the given array is just like yours

klutt
  • 30,332
  • 17
  • 55
  • 95
-2

Arrays don't have .month attributes associated with them. Look in your code below.

var input = [
  {month: "Jan", value: 3},
  {month: "Jan", value: 3.5},
  {month: "Feb", value: 2.1},
  {month: "Mar", value: 6},
  {month: "Apr", value: 4.3},
  {month: "May", value: 5.5},
  {month: "Jun", value: 7},
  {month: "Jun", value: 9},
  {month: "Jul", value: 7},
  {month: "Jul", value: 9},
  {month: "Jul", value: 7},
  {month: "Aug", value: 9},
  {month: "Sep", value: 9},
  {month: "Sep", value: 9},
  {month: "Oct", value: 8},
  {month: "Oct", value: 5},
  {month: "Oct", value: 3},
  {month: "Nov", value: 12},
  {month: "Nov", value: 19.5},
];

// your code with error correction

result = []

for (var i = 0; i < input.length; i++)
{
  var data = input[i]; // this is redundant but we can keep it
  var found = false;
  for (var j = 0; j < result.length; j++)
  {

    /* ----------------------------------------------------------
       ------------------------- HERE ------------------------
    ---------------------------------------------------------- */

    //if (result[j].month === data.month)
    // your if statement was never hit, because result[j] is an array
    // and doesn't have a month attribute, so it should return null,
    // thus never hitting your if statement
    if (result[j][0] === data.month)
    {
      found = true;
      result[j][1] += data.value;
      break;
    }
  }
  if (!found) {
    result.push([data.month, data.value]);
  }
}

console.log(result)
Shmack
  • 1,933
  • 2
  • 18
  • 23