khany
khany

Reputation: 1187

Is this the correct way to use JS.map?

I am trying to get a count of all the objects in an array (this.players) where object.alive == true.

So far I have:

return this.players.map(el => el.alive).reduce(function(acc, cur) {
    if(acc === true) {
      if(cur === true) {
        acc = 1
      } else {
        acc = 0
      }
    }
    return acc + ((cur) ? 1 : 0)
  })

which looks ugly as sin but appears to work. Is there a more robust way to do this?

Upvotes: 0

Views: 57

Answers (4)

le_m
le_m

Reputation: 20228

Array.reduce is a good choice as it avoids computation of a filtered array when you actually just want the number of alive players, not the players itself.

Your issue is within the reduce callback: acc accumulates the number of alive players, so you shouldn't compare it to true.

Also, instead of resetting that number via acc = 1 or acc = 0 you probably meant to write acc += 1.

Additionally, instead of mapping players to their alive property, just access that property directly within the reduce callback:

let players = [{alive: true}, {alive: false}, {alive: false}, {alive: true}];

let alive = players.reduce((alive, next) => next.alive ? alive + 1 : alive, 0);

console.log(alive);

Upvotes: 1

Mohamed Abbas
Mohamed Abbas

Reputation: 2278

I think filter will be good for your case

let players = [{alive: true}, {alive: false}, {alive: false}, {alive: true}]

let alivePlayersNum = players.filter( player =>  player.alive).length;

console.log(alivePlayersNum);

Upvotes: 0

Maciej Caputa
Maciej Caputa

Reputation: 1891

Use Array.prototype.filter() which creates a new array with all elements that pass the test implemented by the provided function.

return this.players.filter(player => player.alive).length;

Upvotes: 0

Simeon Simeonoff
Simeon Simeonoff

Reputation: 146

Try filter, it works like map returning an array of filtered objects.

return this.players.filter(player => player.alive);

Upvotes: 0

Related Questions