Chartjs-Sum array of objects value based on month – ReactJS

1👍

You can massively simplify the solution using the fact that values for month are always going to be between 1-12 (inclusive). Therefore you can use an array of length 12 and use month - 1 as an index to update the sum for a given month.

const myArray = [{
  date: "2022-04-13",
  vat_percentages: {
    21: 92.31
  },
  total: 92.31
}, {
  date: "2022-05-04",
  vat_percentages: {
    21: 21.24
  },
  total: 21.24
}, {
  date: "2022-05-05",
  vat_percentages: {
    21: 47.41
  },
  total: 47.41
}]

const labelValues = myArray.reduce((acc, curr) => {
  // parse a month to number e.g. "04" => 4 then substract 1 to get the index within the array 4 - 1 => 3
  const idx = Number(curr.date.split("-")[1]) - 1;
  acc[idx] += curr.total;
  return acc
}, new Array(12).fill(0))

console.log(labelValues)
.as-console-wrapper { max-height: 100% !important; top: 0; }

The output should be interpreted as follows:

0 (Jan) 1 (Feb) 2 (Mar) 3 (Apr) 4 (May) 5 (Jun) 6 (Jul) 7 (Aug) 8 (Sep) 9 (Oct) 10 (Nov) 11 (De)
0 0 0 92.31 68.64999999999999 0 0 0 0 0 0 0

Edit

To reflect your requirement of having to set the values at certain positions according to generatedMonths you could use simple modular arithmetic.

A position for a month is therefore obtained by (month + shiftValue) % 12. To determine the shift value you just need to look at the first value in generatedMonths and lookup which month of the year that is.
The rest works exactly like before:

const myArray = [{
  date: "2022-04-13",
  vat_percentages: {
    21: 92.31
  },
  total: 92.31
}, {
  date: "2022-05-04",
  vat_percentages: {
    21: 21.24
  },
  total: 21.24
}, {
  date: "2022-05-05",
  vat_percentages: {
    21: 47.41
  },
  total: 47.41
}]

// mapping of month to shift value
const mapping = {
  Jan: 0,
  Feb: 11,
  Mar: 10,
  Apr: 9,
  May: 8,
  Jun: 7,
  Jul: 6,
  Aug: 5,
  Sep: 4,
  Oct: 3,
  Nov: 2,
  Dec: 1
};
// compute a shift value
const generatedMonths = ["Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", "May"]
const shiftBy = mapping[generatedMonths[0]];
const labelValues = myArray.reduce((acc, curr) => {
  // parse a month to number e.g. "04" => 4 then substract 1 to get the index within the array 4 - 1 => 3
  const idx = (Number(curr.date.split("-")[1]) + shiftBy - 1) % 12;
  acc[idx] += curr.total;
  return acc
}, new Array(12).fill(0))

console.log(labelValues)

Leave a comment