Count Item Occurrences in an Array JavaScript Solution

Happy day 7 of 365 Days of Coding! 1 week down 52 to go. A JavaScript solution for a function that counts how many times something shows up in an array. This can be a flat array or an array of arrays.

Disclaimer: there are MANY ways to solve this problem this is an answer that I would see or use in a coding interview and would accept as a proper answer

TLDR: Solution is at the bottom of the post

The Problem

Create a function that accepts an array and an item and counts the number of times that item shows up in the array. Do not ignore capitalization, punctuation, or spaces.

Examples:

      itemCounter(["hello", [["Hello", "hello"], [["Hello"]], "Hello", "world"]], "hello"); // 2

      itemCounter([["A", "A", "A", "A", "A", "a"],
        ["a", "A", "A", "A", "A", "A"],
        ["A", "a", "A", "A", "A", "A"],
        ["A", "A", "A", "a", "A", "A"]], "a"); // 4

      itemCounter([1, 2, [3], [4, 5], [4, [[6, 7], 4]]], 4); // 3

      itemCounter([1, 2, [3, 11], [4, 5], [4, [[6, 7], 4]]], 10) // 0

The Solution

Lets write down what we will need to do

  • possibility 1

    • create a function that accepts an array and an item to find in that array

    • create a variable for a counter

    • flatten the array

    • loop through the array

      • every time the item is found in that array increment the counter

    • return the counter at the end

  • possibility 2

    • create a function that accepts an array and an item to find in that array

    • flatten the array

    • filter the array by the item that was passed in

    • get the length of that array

Solution 1

First we need to create a function that accepts an array and an item

const itemCounter = (array, item) => {
    //create a variable for a counter
    //flatten the array
    //loop through the array
        //every time the item is found in that array increment the counter
    //return the counter at the end
}

Create a variable that will hold a counter

const itemCounter = (array, item) => {
    let counter = 0
    //flatten the array
    //loop through the array
        //every time the item is found in that array increment the counter 
    //return the counter at the end
}

We need to flatten the array and since we don’t know how many nested arrays there are we are going to pass .flat() Infinity. .flat() will flatten an array the same number of times you pass to it. Since we don’t know how many times this will be we will pass Infinity, which will flatten the array until it is completely flat.

const itemCounter = (array, item) => {
    let counter = 0
    array.flat(Infinity)
    //loop through the array
        //every time the item is found in that array increment the counter
    //return the counter at the end
}

We want to loop through the flattened array so I am going to chain a .forEach on the .flat(). This is a lot like a for loop just a different syntax. To read more about it check out this MDN page.

const itemCounter = (array, item) => {
    let counter = 0
    array.flat(Infinity).forEach(x => {
    })
    //every time the item is found in that array increment the counter 
}

If the item that we are currently on in the forEach loop matches the item that is passed we want to increment the counter. If not we want to continue the loop.

const itemCounter = (array, item) => {
  let counter = 0
  array.flat(Infinity).forEach(x => {
    if(x == item){ counter++ }
  });
  //return counter
}

Last but not least we need to return the counter.

const itemCounter = (array, item) => {
  let counter = 0
  array.flat(Infinity).forEach(x => {
    if(x == item){ counter++ }
  });
  return counter
}

Solution 2

First we need to create a function that accepts an array and an item and flatten the array. This will be the same as the previous solution.

const itemCounter = (array, item) => {
  array.flat(Infinity)
  //filter the array by the item that was passed in
  //get the length of that array
}

To filter the array we are going to use .filter(). If you are unfamiliar with it you can check out this MDN page but it creates a new array of the elements that meet the criteria in the function that you pass it.

const itemCounter = (array, item) => {
  array.flat(Infinity).filter(currentItem => currentItem === item)
  //get the length of that array
}

Now we just have to get the length. I am also going to clean it up a bit and we get this.

const itemCounter = (array, item) => array.flat(Infinity).filter(currentItem => currentItem == item).length;

Conclusion

In this case the performance for each is the same. I like the second solution because its substantially less code and its still easy to read but both solutions are good. Below are my jsbench results for those who are curious.

jsbench.PNG

I hope you had fun with this one! Please leave your solutions that you came up with in the comments section. If you have any challenge you would like to see done also leave that in the comments below you may see it come up! If you would like to get the challenge emailed to you every day in morning and a notification when the solution is posted subscribe below!

Previous
Previous

Day 8 Challenge

Next
Next

Day 7 Challenge