Skip to main content

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

A very common data processing task is to count the frequency of each unique element in an array. This is often called creating a "frequency map" or "histogram." For example, given ['a', 'b', 'a'], you would want to produce an object like { a: 2, b: 1 }.

This guide will teach you the modern and standard methods for solving this problem. You will learn how to use the powerful Array.prototype.reduce() method for a concise solution, and see how to use a Map for a more flexible and often more robust alternative.

Core Method (Most Concise): Array.prototype.reduce()

The reduce() method is the perfect functional tool for transforming an array into a single value, which in this case is our frequency map object. It iterates over the array while building up an accumulator object.

For example, we have an array with duplicate values and we need an object that counts each one.

// Problem: How to count the occurrences of each element?
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];

Solution:

const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];

const fruitCount = fruits.reduce((accumulator, fruit) => {
accumulator[fruit] = (accumulator[fruit] || 0) + 1;
return accumulator;
}, {});

console.log(fruitCount); // Output: { apple: 3, banana: 2, orange: 1 }

How It Works

  • reduce((accumulator, fruit) => {...}, {}): We initialize reduce with an empty object ({}) as the starting value for our accumulator.
  • accumulator[fruit] = ...: On each iteration, we use the current element (fruit) as a key on our accumulator object.
  • (accumulator[fruit] || 0) + 1: This is a clever one-liner.
    • It tries to get the current count for the fruit: accumulator[fruit].
    • If the fruit hasn't been seen before, this value will be undefined. The logical OR (||) operator will then default to 0.
    • We then add 1 to this value, either incrementing the existing count or initializing a new one at 1.

An Alternative Method (More Flexible): Using a Map

While using a plain object is very common, a Map is often a more robust choice for a frequency map, especially if your array might contain keys that are not strings (e.g., numbers or even objects).

In the following example, the logic is very similar, but we use the .get() and .set() methods of the Map.

const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];

const fruitCount = new Map();

for (const fruit of fruits) {
const currentCount = fruitCount.get(fruit) || 0;
fruitCount.set(fruit, currentCount + 1);
}

console.log(fruitCount);
// Output: Map(3) { 'apple' => 3, 'banana' => 2, 'orange' => 1 }

// You can easily access the count for a specific item
console.log(fruitCount.get('apple')); // Output: 3
note

This Map-based approach is considered a best practice in modern JavaScript for its flexibility and clear, explicit methods.

The Traditional Method: The for...of Loop

For those who prefer an imperative style, a for...of loop is a perfectly readable and efficient way to build the frequency map object. The logic is identical to the reduce method but is written out step-by-step.

const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];

const fruitCount = {};

for (const fruit of fruits) {
if (fruitCount[fruit]) {
// If the fruit is already a key, increment its count
fruitCount[fruit]++;
} else {
// Otherwise, initialize it to 1
fruitCount[fruit] = 1;
}
}

console.log(fruitCount);
// Output: { apple: 3, banana: 2, orange: 1 }
note

This can also be written with the same concise || trick used in the reduce example:

for (const fruit of fruits) {
fruitCount[fruit] = (fruitCount[fruit] || 0) + 1;
}

Conclusion

Creating a frequency map is a common and useful data transformation. Modern JavaScript offers several clean and effective ways to do it.

  • The reduce() method is the most concise and functional approach for creating a plain object. It is a very common pattern in modern JavaScript codebases.
  • Using a Map with a for...of loop is a more robust and flexible solution, especially if your array elements are not strings. This is often considered the modern best practice.
  • A traditional for...of loop with a plain object is also a perfectly valid, readable, and efficient solution.