4

Having an array like this:

const data = [
    {
        "name": "Dave",
        "coins": 14,
        "weapons": 2,
        "otherItems": 3,
        "color": "red"
    },
    {
        "name": "Vanessa",
        "coins": 18,
        "weapons": 1,
        "otherItems": 5,
        "color": "blue"
    },
    {
        "name": "Sharon",
        "coins": 9,
        "weapons": 5,
        "otherItems": 1,
        "color": "pink"
    },
    {
        "name": "Walter",
        "coins": 9,
        "weapons": 2,
        "otherItems": 4,
        "color": "white"
    }
]

How to count sum of coins, weapons and otherItems using ES6 features? (I'm not attached to this: any simple method would be good.)

data.reduce((first, last) => first + last) generates a chain of [object Object][object Object]s...

2
  • what do you like to count? do you have an example of the result? Commented Apr 10, 2020 at 16:23
  • All the countable values :-) As I wrote, coins, weapons and otherItems. Commented Apr 10, 2020 at 16:33

4 Answers 4

5

You have to process every field separately (note that when you don't specify second parameter for reduce it will take first array object as seed and start processing from the second one):

const data = [
    {
        "name": "Dave",
        "coins": 14,
        "weapons": 2,
        "otherItems": 3,
        "color": "red"
    },
    {
        "name": "Vanessa",
        "coins": 18,
        "weapons": 1,
        "otherItems": 5,
        "color": "blue"
    },
    {
        "name": "Sharon",
        "coins": 9,
        "weapons": 5,
        "otherItems": 1,
        "color": "pink"
    },
    {
        "name": "Walter",
        "coins": 9,
        "weapons": 2,
        "otherItems": 4,
        "color": "white"
    }
]

let result = data.reduce((a,c)=> ({ 
     coins: a.coins + c.coins, 
     weapons: a.weapons + c.weapons, 
     otherItems: a.otherItems + c.otherItems })
)

console.log(result);

Sign up to request clarification or add additional context in comments.

1 Comment

To provide coverage for the case of a single object in the array you'll need to provide an initialValue reduce((a,c)=> { ... }, {coins: 0, weapons: 0, otherItems: 0}).
2

You could take an array of wanted keys for the sums and create an object for the sums and add the wanted values.

const
    data = [{ name: "Dave", coins: 14, weapons: 2, otherItems: 3, color: "red" }, { name: "Vanessa", coins: 18, weapons: 1, otherItems: 5, color: "blue" }, { name: "Sharon", coins: 9, weapons: 5, otherItems: 1, color: "pink" }, { name: "Walter", coins: 9, weapons: 2, otherItems: 4, color: "white" }],
    keys = ['coins', 'weapons', 'otherItems'],
    sums = data.reduce(
        (r, o) => (keys.forEach(k => r[k] += o[k]), r), 
        Object.fromEntries(keys.map(k => [k, 0]))
    );

console.log(sums);

Comments

1

You can use Array.prototype.reduce for this.

To make it a little bit more flexible and dynamic, make a Set of keys you want to get a count of.

Then go through each key in the Set and if that key is in the obj, sum it up in an accumulator object in the reduce callback:

const data = [{"name":"Dave","coins":14,"weapons":2,"otherItems":3,"color":"red"},{"name":"Vanessa","coins":18,"weapons":1,"otherItems":5,"color":"blue"},{"name":"Sharon","coins":9,"weapons":5,"otherItems":1,"color":"pink"},{"name":"Walter","coins":9,"weapons":2,"otherItems":4,"color":"white"}]

//Keys to count
const keys = new Set(["coins", "weapons", "otherItems"]);

const count = data.reduce((acc, obj) => {
  const objKeys = keys.forEach(key => {
    if (obj.hasOwnProperty(key)) {
      acc[key] = (acc[key] || 0) + obj[key];
    }
  });
  return acc;
}, {});
console.log(count);

Comments

0

Your idea is right, you need to use reduce method. The problem is that you're summing two objects, not their properties. All you need to do is change the code to the following (to sum the coins):

data.reduce((first, last) => first.coins + last.coins, 0)

And following for weapons:

data.reduce((first, last) => first.weapons + last.weapons, 0)

3 Comments

Unfortunately, this gives NaN as a result. @mickl's answer seems to be right.
I forgot the initial value, edited the answer now, so it should be working
Still NaN here... The accumulator (first) shouldn't refer to any key: this will work: data.reduce((first, last) => first + last.coins, 0).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.