Count elements in nested array

Given a nested array and a callback function, count all the elements that pass the test in the callback and return the count.

Example

Input:
const arr = [[1, [2, [3, 4, "foo", { a: 1, b: 2 }]], "bar"]];
const count = countInArray(arr, (e) => typeof e === "number");
console.log(count);

Output:
4

Whenever I hear the word nested in a problem, my mind automatically moves to a recursive solution. We will be using the same to solve this problem.

Though it can be done Iteratively as well, I find it easy to do it recursively.

All we have to do is create a closure with an inner function. The parent function will hold the variable which will be incrementing the count every time the array element passes the test in the callback function and the inner function will recursively search the nested array.

In the inner function, we will iterate each element of the array and test it with the callback function, if it passes the test then increment the count, irrespective if the element is an array then recursively call the same function with the current value for nested search.

let countInArray = function (inputArr, test) {
  //track the count
  let count = 0;

  const search = (arr, test) => {
    //iterate the array
    for (let a of arr) {
      //if not an array
      //test the element
      //if it passes the test, store its result
      if (test(a)) {
        count += 1;
      }

      //if sub-array
      if (Array.isArray(a)) {
        //recursively filter the sub-array
        search(a, test);
      }
    }
  };

  //search
  search(inputArr, test);

  //return
  return count;
};
Input:
const arr = [[1, [2, [3, 4, "foo", { a: 1, b: 2 }]], "bar"]];
const count = countInArray(arr, (e) => typeof e === "number");
console.log(count);

Output:
4