Map-Reduce : How to count in a collection

Question

Important edit : I can't use filter - the purpose is pedagogic.

I have an array in which I would want to count the number of its elements that verify a boolean, using only map and reduce.

Count of the array's size

I already wrote something that counts the array's size (ie. : the number of all of its elements), using reduce :

const array_numbers = [12, 15, 1, 1]; // Size : 4
console.log(
              array_numbers.reduce((acc) => {
                return acc + 1;
              }, 0)
);

Count of the array's elements checking a boolean condition

Now I would want to count only the elements that verify a boolean condition. Thus, I must use map before reduce and the elements of the map's returned array will be only the good elements.

So I wrote this code but it doesn't work... Indeed, I put null when I encounter a not-good element (and null is counted as en element unfortunately).

NB : here, the boolean condition is "is the element even ? (%2 == 0)".

const array_numbers = [12, 15, 1, 1]; // Size : 4
console.log(
              array_numbers.map((current_value) => {
                if(current_value % 2 == 0) {
                  return current_value;
                }
                return null;

              }).reduce((acc) => {
                return acc + 1;

              }, 0)
);

Show source
| javascript   | arrays   | reduce   | mapreduce   2017-01-03 17:01 4 Answers

Answers to Map-Reduce : How to count in a collection ( 4 )

  1. 2017-01-03 17:01

    Array#filter the array and check the length:

    const array_numbers = [12, 15, 1, 1];
    const result = array_numbers.filter((n) => n % 2 === 0).length;
    
    console.log(result);

    Or count using Array#reduce:

    const array_numbers = [12, 15, 1, 1, 4];
    const result = array_numbers.reduce((r, n) => n % 2 ? r : r + 1, 0);
    
    console.log(result);

    Or if you must, you can use Array#map with Array#reduce:

    const array_numbers = [12, 15, 1, 1, 4];
    const result = array_numbers
      .map((n) => n % 2 === 0 ? 1 : 0) // map to 1 or 0 according to the condition
      .reduce((r, n) => r + n); // sum everything
    
    console.log(result);

  2. 2017-01-03 17:01

    You can use Array.prototype.filter to filter the even numbers - and you don't need the reduce() function - you can use length of the array returned by the filter() function.

    Or you can use reduce() method alone like below:

    See demos below:

    const array_numbers = [12, 15, 1, 1]; // Size : 4
    
    // using filter
    console.log(
      array_numbers.filter((current_value) => {
        return current_value % 2 == 0;
      }).length
    );
    
    // using reduce
    console.log(
      array_numbers.reduce((prev, curr) => {
        return curr % 2 == 0 ? prev + 1 : prev;
      }, 0)
    );

  3. 2017-01-03 17:01

    Since per your comment you must use reduce for some reason:

    arr.reduce((acc, n) => { n % 2 ? acc + n : acc }, 0);
    

    The map is unecessary.

  4. 2017-01-03 18:01

    As Jared Smith mentioned, you don't need to use map for this task. Array.reduce() gets the current element as a second argument in the callback function which you can use to check if it satisfies your given condition.

    So, again assuming that you must use either map and/or reduce:

    const myArray = [1,2,3,4,5,6];
    const condition = function(a) {
      // let's say
      return a %2 == 0;
    }
    
    let result = myArray.reduce((acc, val) => {
      return condition(val) ? acc + 1 : acc
      }, 0);
    
    console.log(result);

Leave a reply to - Map-Reduce : How to count in a collection

◀ Go back