How to Count Element Occurrences in a JavaScript Array

Exploring ways to count occurrences of each and single element in a JavaScript array. 3 methods for each case.
Published 2023-03-11 5 min read
How to Count Element Occurrences in a JavaScript Array

Counting element occurrences in an array is a common task in JavaScript programming. This article will explore different approaches to counting element occurrences in a JavaScript array, from using a simple loop to leveraging built-in array methods.

We’ll go through two scenarios: first, counting occurrences of a single specific element, and second, tallying occurrences of all elements within the array.

By the end of this article, you’ll have a solid understanding of how to count element occurrences in an array, and be equipped with the knowledge to apply it to your own projects.

In all examples we assume that we operate on an array in such a format:

const array = [2, 4, 6, 1, 6, 7, 3, 4, 3, 3, 0, 2];

Counting occurrences of all elements in a Javascript array

The first scenario assumes you are interested in counting occurrences of each element and gathering the result in some way. In all proposed cases this result is an object - keys correspond to the element names, and values are occurrence counts (sidenote: it’s a similar concept to the tally method from Ruby).

Meh method: for-loop-based counting

const counts = {};
for (let i = 0; i < array.length; i++) {
  const element = array[i];
  counts[element] ? counts[element]++ : (counts[element] = 1);
}

In counts we’ll collect the results, this pattern will continue in this article. The next step is to iterate over the array. It’s cumbersome as an additional step is needed for fetching the element. If the count for an element exists then we should increase it by 1, otherwise, we should assign 1.

I don’t like it, as a classic for loop needs some boilerplate that doesn’t convey anything meaningful.

Better method: forEach-based counting

This time we’ll iterate over the array with forEach, eliminating one line and some boilerplate.

const counts = {};
array.forEach((element) => {
  counts[element] ? counts[element]++ : (counts[element] = 1);
});

It does pretty much the same, but it’s more javascripty and much more expressive. Don’t you think?

Another variation, that avoids ternary operator looks like this:

const counts = {};
array.forEach((element) => {
  counts[element] ||= 1;
  counts[element]++;
});

More lines, but superior readability in my opinion.

Fewer lines, more cryptic method: reduce-based counting

const counts = array.reduce((acc, element) => {
  acc[element] ? acc[element]++ : (acc[element] = 1), acc;
}, {});

This one introduces a different function, called reduce. What this does is it goes through the array, but the result is accumulated in the… accumulator. In our case, it’s acc variable that starts as {} (second argument of reduce function). The annoying thing is on each line we have to return a new accumulator value. This can be written as a one-liner, but readability suffers. That’s why I would not recommend it.

So for me, forEach method is a winner, as it’s the most readable of the bunch.

Counting occurrences of a single element in JavaScript

In the second scenario, we want to count occurrences for a given value. This is a simpler scenario, but still, we can address it in a few ways.

Meh method: for-loop-based counting

const yourValue = 2;
let count = 0;
for (let i = 0; i < array.length; i++) {
  if (array[i] === yourValue) count++;
}

Nothing special it’s very similar to the C++ equivalent. We can do it better.

Better method: counting using filter

Ok, let’s use some JavaScript standard library.

const yourValue = 2;
const count = array.filter((element) => element === yourValue).length;

It’s much shorter and much more expressive. The filter method selects elements from the array that return truthy values for a given callback. Therefore we get a new array that contains only elements that match our criteria.

Overly clever method: counting with reducer

There are a few ways to use reduce method in this case. The most readable is:

array.reduce((acc, element) => (element === yourValue ? acc + 1 : acc), 0);

Of course, we can shorten it.

array.reduce((acc, element) => (element === yourValue ? ++acc : acc), 0);

Notice that we had to use prefix increment operand, to increase the acc value before returning it. Creating such a gotcha in your code might not be a great idea.

There’s an even shorter way to write it…

array.reduce((acc, element) => acc + element === yourValue, 0);

…but it’s just bad, as it relays on weird internal JavaScript conversions. Basically, if you add anything to Number it has to be casted to a Number. true in such a case is casted to 1, false is casted to 0.

Anyway, I recommend the filter method in this case, as it’s concise and readable.

Closing thoughts

In conclusion, counting element occurrences in a JavaScript array can be accomplished in various ways, depending on the specific use case and personal preferences.

While the classic for loop can get the job done, there are more expressive and concise methods available, such as forEach and filter.

The reduce method, while powerful, can often lead to less readable code and should be used with caution.

By understanding these different approaches, you’ll be able to efficiently count element occurrences in arrays and apply this knowledge to your own projects. So go ahead and experiment with these methods, and see which one works best for you!

#javascript