Home > OS >  Sum up value on hour in javascript array [duplicate]
Sum up value on hour in javascript array [duplicate]

Time:10-07

I have an array with values per date but would like to sum up all values on hour instead of separate date/hour. I guess I could iterate over it and remove yyyy-mm-dd and then sum up on duplicate hour object but is there a smarter way?

  {
    "series": [
      {
        "value": 1,
        "category": "2021-03-04T04:00:00.000"
      },
      {
        "value": 2,
        "category": "2021-03-04T05:00:00.000"
      },
      {
        "value": 3,
        "category": "2021-03-04T06:00:00.000"
      },
      {
        "value": 1,
        "category": "2021-03-05T04:00:00.000"
      },
      {
        "value": 2,
        "category": "2021-03-05T05:00:00.000"
      },
      {
        "value": 3,
        "category": "2021-03-05T06:00:00.000"
      }
    ]
  }
]

So the array below should only be:

[
  {
    "series": [
      {
        "value": 2,
        "category": "04:00:00.000"
      },
      {
        "value": 4,
        "category": "05:00:00.000"
      },
      {
        "value": 6,
        "category": "06:00:00.000"
      }
    ]
  }
]

CodePudding user response:

Use Array.reduce

Logic

  • Loop through input with Array.reduce.
  • Get the time node from each category by splitting the sting on T.
  • Check if a node with same time exist in accumulator.
  • If yes, add the current value to the value of existing node.
  • Or else push a new node with value and category.

const data = {
  series: [
    { value: 1, category: "2021-03-04T04:00:00.000" },
    { value: 2, category: "2021-03-04T05:00:00.000" },
    { value: 3, category: "2021-03-04T06:00:00.000" },
    { value: 1, category: "2021-03-05T04:00:00.000" },
    { value: 2, category: "2021-03-05T05:00:00.000" },
    { value: 3, category: "2021-03-05T06:00:00.000" },
  ],
};
const result = data.series.reduce((acc, curr) => {
  const time = curr.category.split("T")[1];
  const accNode = acc.find((node) => node.category === time);
  if (accNode) {
    accNode.value  = curr.value;
  } else {
    acc.push({ value: curr.value, category: time });
  }
  return acc;
}, []);
console.log({
  series: result,
});

CodePudding user response:

Map and reduce - you can split in the reduce but this is more readable

const data = {
  "series": [
  { "value": 1, "category": "2021-03-04T04:00:00.000" },
  { "value": 2, "category": "2021-03-04T05:00:00.000" },
  { "value": 3, "category": "2021-03-04T06:00:00.000" },
  { "value": 1, "category": "2021-03-05T04:00:00.000" },
  { "value": 2, "category": "2021-03-05T05:00:00.000" },
  { "value": 3, "category": "2021-03-05T06:00:00.000" }
  ]
}
const newData = data.series
  .map(item => ({value:item.value, category: item.category.split("T")[1]}))
  .reduce((acc,cur) => { 
    const item = acc.find(({category}) => category === cur.category);
    if (item) item.value  = cur.value;
    else acc.push(cur);
    return acc;
  },
  [])
console.log(newData)

  • Related