Mr B
Mr B

Reputation: 4130

How to sum values in an array of objects in javascript

I have an array of objects, like so:

[
    {
        Daypart: "G_POSTPEAK",
        day_of_week: "Monday",
        uplift: 1
    },
    {
        Daypart: "A_BREAKFAST",
        day_of_week: "Thursday",
        uplift: 1
    },
    {
        Daypart: "C_DAYTIME",
        day_of_week: "Sunday",
        uplift: 2
    },
    {
        Daypart: "G_POSTPEAK",
        day_of_week: "Monday",
        uplift: 2
    },
]

I have only shown a sample of objects in the array, I am working with a lot more. They all have the specified properties, the daypart property could be one of 8 values and the day of week value could be one of 7 (days of the week).

I want to return the sum of the uplift value for all the objects that have the same daypart and day_of_week value.

So the above should return something like:

{
    G_POSTPEAK_Monday: {
        Daypart: "G_POSTPEAK",
        day_of_week: "Monday",
        uplift: 3
    },
    A_BREAKFAST_Thursday: {
        Daypart: "A_BREAKFAST",
        day_of_week: "Thursday",
        uplift: 1
    },

    C_DAYTIME_Sunday: {
        Daypart: "C_DAYTIME",
        day_of_week: "Sunday",
        uplift: 2
    }
}

Appreciate any help

Upvotes: 1

Views: 3502

Answers (5)

Abu Bakar
Abu Bakar

Reputation: 65

You can use loadash package to perform this in optimized way...

let _ = require('lodash');
let arrays = [
  {
    'name':'monday',
    vaue:1
  },
 {
    'name':'monday',
    vaue:2
 },
 {
    'name':'tuesday',
    vaue:3
 },
 {
   'name':'wednesday',
   vaue:11
 },
 {
   'name':'wednesday',
   vaue:11
 },
]

let newarray = _(arrays).groupBy("name").map(   (name) => ({
   name: name,
   value0: _.sumBy(name, 'vaue')
 }))
 .value()
console.log(newarray);

Upvotes: 0

Scott Sauyet
Scott Sauyet

Reputation: 50787

A somewhat more functional version, using reduce like several other solutions.

const combine = inputs => Object .values (
  inputs .reduce ((a, {Daypart, day_of_week, uplift}) => {
    const key = `${Daypart}|${day_of_week}`
    return {...a, [key]: ({
      Daypart, 
      day_of_week, 
      uplift: (a[key] && a[key].uplift || 0) + uplift
    })}
  }, {})
)

let inputs = [
  {Daypart: "G_POSTPEAK", day_of_week: "Monday", uplift: 1},
  {Daypart: "A_BREAKFAST", day_of_week: "Thursday", uplift: 1},
  {Daypart: "C_DAYTIME", day_of_week: "Sunday", uplift: 2},
  {Daypart: "G_POSTPEAK", day_of_week: "Monday", uplift: 2},
]

console .log (
  combine (inputs)
) 

Upvotes: 0

Hassan Imam
Hassan Imam

Reputation: 22524

You can use array#reduce to group data based on the Daypart and day_of_week in an object accumulator.

let data = [ { Daypart: "G_POSTPEAK", day_of_week: "Monday", uplift: 1 }, { Daypart: "A_BREAKFAST", day_of_week: "Thursday", uplift: 1 }, { Daypart: "C_DAYTIME", day_of_week: "Sunday", uplift: 2 }, { Daypart: "G_POSTPEAK", day_of_week: "Monday", uplift: 2 }],
    result = data.reduce((r,o) => {
      let key = `${o.Daypart}_${o.day_of_week}`;
      r[key] = r[key] || {...o, uplift: 0};
      r[key].uplift += o.uplift;
      return r;
    },{});
console.log(result);
.as-console-wrapper {max-height: 100% !important; top: 0;}

Upvotes: 0

Abu Bakar
Abu Bakar

Reputation: 65

You can use ES6 reduce function to perform the sum in one line instead of using foreach.

let array = [
    {
        Daypart: "G_POSTPEAK",
        day_of_week: "Monday",
        uplift: 1
    },
    {
        Daypart: "A_BREAKFAST",
        day_of_week: "Thursday",
        uplift: 1
    },
    {
        Daypart: "C_DAYTIME",
        day_of_week: "Sunday",
        uplift: 2
    },
    {
        Daypart: "G_POSTPEAK",
        day_of_week: "Monday",
        uplift: 2
    },
];

const totalUplift = array.reduce((acc, array) => acc + array.uplift, 0);

console.log(totalUplift);

Upvotes: 0

Adarsh
Adarsh

Reputation: 827

The following function can be used. I have used ES6. The function takes inputs which will be your input object.

const sumIt = (inputs) => {
  const result = {};
  inputs.forEach((input) => {
    const key = `${input.Daypart}_${input.day_of_week}`;
    if (key in result) {
      result[key].uplift = result[key].uplift + input.uplift;
    } else {
      result[key] = { ...input };
    }
  });
  return result;
};

Upvotes: 1

Related Questions