bzlight
bzlight

Reputation: 1150

Sum values of matching keys in array of objects

Problem

I need to sum the values of matching keys in a nested array of objects. There are two sub objects inside each object. I need to sum the values of the second nest object. Your help would be greatly appreciated! I know there are other similar questions but their inputs are formatted differently so working off their examples is giving me a lot of trouble since I'm new to JS

Array to sum

It has more than two objects in the array but I only included two for brevity.

stats: [
    0: {
        statsFields: {
            duo: 2
            duoM: 2
            duoW: 2
            kdr: 2
            solo: 2
            soloM: 2
            soloW: 2
            squad: 2
            squadM: 2
            squadW: 2
            total: 2
            totalM: 1
            totalW: 2
            winP: 2
        },
        _id: "5cc283ba7b752f322ce26168"
    },
    1: {
        statsFields: {
            duo: 2
            duoM: 2
            duoW: 2
            kdr: 2
            solo: 2
            soloM: 2
            soloW: 2
            squad: 2
            squadM: 2
            squadW: 2
            total: 2
            totalM: 1
            totalW: 2
            winP: 2
        },
        _id: "5cc284cd7b752f322ce26169"
    },
]

Desired Output

statsFields: {
    duo: 4
    duoM: 4
    duoW: 4
    kdr: 4
    solo: 4
    soloM: 4
    soloW: 4
    squad: 4
    squadM: 4
    squadW: 4
    total: 4
    totalM: 2
    totalW: 4
    winP: 4
}

What I've tried

I've tried a reducer with a map and I've also tried a for loop but I'm having trouble because the object is so deeply nested in the array and there is also a second object in the array I don't need which is producing errors.

Upvotes: 0

Views: 1084

Answers (3)

Slai
Slai

Reputation: 22876

If the data is from a JSON string, it can also be done during parsing :

var result = {}, json = '{"stats":[{"statsFields":{"duo":2,"duoM":2,"duoW":2,"kdr":2,"solo":2,"soloM":2,"soloW":2,"squad":2,"squadM":2,"squadW":2,"total":2,"totalM":1,"totalW":2,"winP":2},"_id":"5cc283ba7b752f322ce26168"},{"statsFields":{"duo":2,"duoM":2,"duoW":2,"kdr":2,"solo":2,"soloM":2,"soloW":2,"squad":2,"squadM":2,"squadW":2,"total":2,"totalM":1,"totalW":2,"winP":2},"_id":"5cc284cd7b752f322ce26169"}]}'

JSON.parse(json, (k, v) => v.toFixed && (result[k] = result[k] + v || v))

console.log( result )

Upvotes: 0

Arup Rakshit
Arup Rakshit

Reputation: 118271

Here is how I'll do this:

var ary = {
    stats: [{
        statsFields: {
            duo: 2,
            duoM: 2,
            duoW: 2,
            kdr: 2,
            solo: 2,
            soloM: 2,
            soloW: 2,
            squad: 2,
            squadM: 2,
            squadW: 2,
            total: 2,
            totalM: 1,
            totalW: 2,
            winP: 2,
        },
        _id: "5cc283ba7b752f322ce26168"
    }, {
        statsFields: {
            duo: 2,
            duoM: 2,
            duoW: 2,
            kdr: 2,
            solo: 2,
            soloM: 2,
            soloW: 2,
            squad: 2,
            squadM: 2,
            squadW: 2,
            total: 2,
            totalM: 1,
            totalW: 2,
            winP: 2,
        },
        _id: "5cc284cd7b752f322ce26169"
    },
    ]
}

var res = ary.stats.reduce((acc, cur) => {
    var keys = Object.keys(cur.statsFields)
    return keys.reduce((mem, key) => {
        mem[key] = (acc.statsFields[key] || 0) +( cur.statsFields[key] || 0);
        return mem;
    }, {})
});

console.log(res)

Upvotes: 0

junvar
junvar

Reputation: 11574

let stats = [{
  statsFields: {
    duo: 2,
    duoM: 2,
    duoW: 2,
    kdr: 2,
    solo: 2,
    soloM: 2,
    soloW: 2,
    squad: 2,
    squadM: 2,
    squadW: 2,
    total: 2,
    totalM: 1,
    totalW: 2,
    winP: 2,
  },
  _id: "5cc283ba7b752f322ce26168",
}, {
  statsFields: {
    duo: 2,
    duoM: 2,
    duoW: 2,
    kdr: 2,
    solo: 2,
    soloM: 2,
    soloW: 2,
    squad: 2,
    squadM: 2,
    squadW: 2,
    total: 2,
    totalM: 1,
    totalW: 2,
    winP: 2,
  },
  _id: "5cc284cd7b752f322ce26169",
}];

let sum = stats.reduce((acc, {statsFields}) => {
  Object.entries(statsFields).forEach(([key, value]) => acc[key] = (acc[key] || 0) + value);
  return acc;
}, {});

console.log(sum);

Upvotes: 4

Related Questions