Skip to main content

How to Count the Occurrences of Each Element in an Array in JavaScript

A very common data analysis task is to count the frequency of each unique element in an array. This is useful for creating histograms, summarizing data, or finding the most common value in a list. While you could do this with a manual loop, the most concise and idiomatic modern approach is to use the Array.prototype.reduce() method.

This guide will teach you how to use reduce() to efficiently count element occurrences and build a frequency map. We will also cover the classic for...of loop to illustrate the underlying logic.

The Core Task: Creating a Frequency Map

The goal is to transform an array of values into an object (or a Map) where the keys are the unique elements from the array and the values are the number of times each element appeared. This is often called a "frequency map" or "histogram."

Problem, you have an array with duplicate values and need to count each one.

// Problem: How to count the 'a's, 'b's, and 'c's in this array?
const letters = ['a', 'b', 'a', 'c', 'b', 'a'];

Desired Output: { a: 3, b: 2, c: 1 }

The reduce() method is the perfect tool for this because it is designed to "reduce" an array down to a single value—in this case, our final counts object.

This concise, functional approach is the best practice.

const letters = ['a', 'b', 'a', 'c', 'b', 'a'];

const counts = letters.reduce((accumulator, value) => {
// If the key for the value already exists, increment it.
// Otherwise, initialize it to 1.
accumulator[value] = (accumulator[value] || 0) + 1;
return accumulator;
}, {}); // `{}` is the initial value of our accumulator

console.log(counts); // Output: { a: 3, b: 2, c: 1 }

How the reduce() Method Works

  • reduce((accumulator, value) => { ... }, {}): We call reduce with a callback function and an initial value for our accumulator, which is an empty object {}.
  • First Iteration: accumulator is {}, value is 'a'. The expression accumulator['a'] || 0 evaluates to 0, so we set accumulator['a'] = 0 + 1. The accumulator is now { a: 1 }.
  • Second Iteration: accumulator is { a: 1 }, value is 'b'. accumulator['b'] || 0 is 0, so we set accumulator['b'] = 1. The accumulator is now { a: 1, b: 1 }.
  • Third Iteration: accumulator is { a: 1, b: 1 }, value is 'a'. accumulator['a'] || 0 is 1, so we set accumulator['a'] = 1 + 1. The accumulator is now { a: 2, b: 1 }.
  • This process continues until the final object is returned.

The Manual Looping Method: Using a for...of Loop

The classic imperative approach is to create an empty object and manually populate it within a loop. This is more verbose but can be easier to understand for beginners.

const letters = ['a', 'b', 'a', 'c', 'b', 'a'];
const counts = {};

for (const element of letters) {
if (counts[element]) {
counts[element]++;
} else {
counts[element] = 1;
}
}

console.log(counts); // Output: { a: 3, b: 2, c: 1 }
note

While this works perfectly, the reduce() method is generally preferred in modern JavaScript for its conciseness and declarative style.

Bonus: Counting the Occurrences of a Single, Specific Element

If you don't need to count every element, but just one specific element, the problem becomes much simpler. The best tool for this is Array.prototype.filter().

The logic: Filter the array to get a new array containing only the element you're looking for, then get the length of that new array.

Solution:

const letters = ['a', 'b', 'a', 'c', 'b', 'a'];

const countOfA = letters.filter(element => element === 'a').length;
const countOfB = letters.filter(element => element === 'b').length;

console.log(`The letter 'a' appears ${countOfA} times.`); // Output: 3
console.log(`The letter 'b' appears ${countOfB} times.`); // Output: 2

Conclusion

For counting the occurrences of each element in an array, modern JavaScript offers clean, functional solutions.

  • The reduce() method is the recommended best practice for creating a complete frequency map. It is a concise and powerful functional approach.
  • A for...of loop is a perfectly valid but more verbose, imperative alternative.
  • If you only need to count a single specific element, use the much simpler .filter().length pattern.

By choosing the right method for your specific goal, you can write code that is not only correct but also clean and easy to read.