42

New to javascript and I'm having trouble counting the number of trues in an array of boolean values. I'm trying to use the reduce() function. Can someone tell me what I'm doing wrong?

   //trying to count the number of true in an array
    myCount = [false,false,true,false,true].reduce(function(a,b){
      return b?a++:a;
    },0);
    alert("myCount ="+ myCount);  // this is always 0
gitmole
  • 421
  • 1
  • 4
  • 3
  • 6
    `[false,false,true,false,true].filter(x => x).length` – Andreas Feb 18 '17 at 15:37
  • This worked for me although had to do a little modification to it this was what I was looking for. alert($scope.VendorAnalysisResults[0].cols.filter(x => x.visible == true).length) – Deathstalker Jan 31 '18 at 22:08

5 Answers5

108

Seems like your problem is solved already, but there are plenty of easier methods to do it.

Excellent one:

.filter(Boolean); // will keep every truthy value in an array

const arr = [true, false, true, false, true];
const count = arr.filter(Boolean).length;

console.log(count);

Good one:

const arr = [true, false, true, false, true];
const count = arr.filter((value) => value).length;

console.log(count);

Average alternative:

let myCounter = 0;

[true, false, true, false, true].forEach(v => v ? myCounter++ : v);

console.log(myCounter);
kind user
  • 40,029
  • 7
  • 67
  • 77
  • 1
    Great solution console.log([true,false,true,false,true].filter(Boolean).length); but just out of curiosity how does it work? surely false is a boolean as well? – Jon Sep 16 '20 at 15:00
  • @Jon Yes, false is a boolean of course, however it doesn't work like `typeof value === 'boolean'` that will return always true for every boolean, but it will return true only for truthy values. Then let the `Array#filter` do rest of the job. – kind user Sep 16 '20 at 16:45
10

You're returning a++ when the value is true, which will always be zero. Post-increment happens after the value is retrieved. So on the first iteration, a is 0, and the value of a++ is also 0, even though a is incremented. Because a and b are parameters of the callback, it's a fresh a on each call.

Instead:

myCount = [true, false, true, false, true].reduce(function(a, b) {
  return b ? a + 1 : a;
});

console.log(myCount);
Teocci
  • 7,189
  • 1
  • 50
  • 48
Pointy
  • 405,095
  • 59
  • 585
  • 614
8

Well there are multiple ways you can do it.

  1. Boolean with filter()

     const arrayCount = [false,false,true,false,true].filter(Boolean).length;
     console.log(arrayCount);
    
  2. filter

     const arrayCount = [false,false,true,false,true].filter(item => item).length;
     console.log(arrayCount);
    
  3. reduce()

    const arrayCount = [false,false,true,false,true].reduce((acc, current) => acc + current, 0);
    console.log(arrayCount);
    
  4. Using function

    function arrayCount(arr) {
     let result = [];
     for(let i = 0; i < arr.length; i++) {
         if (arr[i] === true) {
             result.push(arr[i]);
         }
     }
     return result.length;
    }
    
    console.log(arrayCount([false,false,true,false,true]))
    
  5. Using for..of

      function arrayCount(arr) {
          let count = 0;
          for(let element of arr) if(element===true) count++;
          return count;
     }
    
    console.log(arrayCount([false,false,true,false,true]))
    
Melongro
  • 15
  • 4
Avadhut Thorat
  • 997
  • 11
  • 7
5

You should use ++a instead a++ because you have to change the value of a suddenly. a variable will be incremented after its value is returned.

 myCount = [false,false,true,false,true].reduce(function(a,b){
      return b? ++a:a;
    },0);
alert("myCount ="+ myCount); 
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
-2

I am not really sure about this, but a and b aren't numbers.

You shoud do something like :

//trying to count the number of true in an array
myCount = [false,false,true,false,true].reduce(function(a,b){
cpt = 0;
if(a) cpt++;
if(b) cpt++;
return cpt;
},0);
alert("myCount ="+ myCount);  // this is always 0
Youri
  • 7
  • 2
  • That's not true. `a` and `b` are numbers. – Mihai Alexandru-Ionut Feb 18 '17 at 15:42
  • Actually, `a` is the accumulated value from previous returned values and `b` is the value of the current element being iterated. With an array like this, the value is a boolean, which is used directly for the `if` condition. It will be coerced into a number (`0` or `1`) if math is done with it. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce – Scott Marcus Feb 18 '17 at 15:53