5

I can't figure out how can I extract the value of an attribute in my objects and then calculate them.

So I have as follow:

const data = [
   {
      topUp: true, value: 200
   },
   {
      topUp: true, value: 18
   },
   {
      topUp: false, value: 20
   },
   {
      topUp: true, value: 100
   },
]

const totalSpending = data.filter(
   transaction => transaction.topUp == true
);

Now I should get 3 objects. From here I want to get the value of each one like [200, 18, 100] and add them together so my const totalSpending will be 318.

peterh
  • 11,875
  • 18
  • 85
  • 108
Markus Hayner
  • 2,869
  • 2
  • 28
  • 60
  • 3
    You just need to continue your pocessing with a map : `const totalSpending = data.filter( transaction => transaction.topUp ).map(transaction => transaction.value);` – Seblor Mar 05 '19 at 13:02
  • `transaction.topUp == true` is just a verbose way of saying `transaction.topUp` – John Coleman Mar 05 '19 at 13:04

3 Answers3

9

You can achieve this relatively easily using reduce, the conditional operator and destructuring assignment:

const data = [{topUp: true, value: 200}, {topUp: true, value: 18}, {topUp: false, value: 20}, {topUp: true, value: 100}],

res = data.reduce((acc, {topUp, value}) => topUp ? acc + value : acc, 0);
console.log(res);

The above will get the properties topUp and value, and then add value to the accumulator (ie the total sum) if topUp is true, if it is false, it will return acc (and thus won't add to the sum).

Alternatively, you can remove the ternary and use math with booleans:

const data = [{topUp: true, value: 200}, {topUp: true, value: 18}, {topUp: false, value: 20}, {topUp: true, value: 100}],

res = data.reduce((acc, {topUp, value}) => acc + value*topUp, 0);
console.log(res);
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
1

You can use reduce also that is a higher order function available on arrays which will filter out the values as well as add them.

const data = [{
    topUp: true,
    value: 200
  },
  {
    topUp: true,
    value: 18
  },
  {
    topUp: false,
    value: 20
  },
  {
    topUp: true,
    value: 100
  },
]

const totalSpending = data.reduce((aggregator, obj) => {
  return obj.topUp ? aggregator + obj.value : aggregator
}, 0)

console.log(totalSpending)
Hemant Parashar
  • 3,684
  • 2
  • 16
  • 23
0

You can use Array.reduce

const data = [
   {
      topUp: true, value: 200
   },
   {
      topUp: true, value: 18
   },
   {
      topUp: false, value: 20
   },
   {
      topUp: true, value: 100
   },
]

const totalSpending = data.filter(
   transaction => transaction.topUp == true
).reduce((previousValue, nextValue) => {
return previousValue + nextValue.value;
}, 0);

console.log(totalSpending);

It loops through every entry in the list and reduces it to a single value. See also the w3schools page.

Robb216
  • 554
  • 4
  • 10
  • The `+=` is superfluous - `previousValue` is thrown away after the return, so assigning to it is useless. The action of assigning returns the new value assigned, which is then passed to `return` which is then handed over to the next invocation of the `reduce` callback. – VLAZ Mar 05 '19 at 13:15
  • @VLAZ thanks, that makes more sense. I updated my code example. – Robb216 Mar 05 '19 at 14:28