Count Duplicate Values in a JavaScript Array

Cover Image for Count Duplicate Values in a JavaScript Array

To count the number of times a value occurs in a JavaScript array:

  1. Create a new object to keep track of the count for each value in the array. For those familiar with TypeScript, this object's type looks like Record<string, number>
  2. Iterate over the array using .forEach. For reach value, increment its count in the object that we create in step 1

Count how many times a value occurs in an array

Here's a basic approach that allows us to count the number of times a particular value occurs within a JavaScript array.

const initialArray = [
  'one', 'two', 'three',
  'one', 'two', 'three', 'four',
  'one', 'two', 'three', 'four', 'five'
];

// Create a `count` object to keep track of the number of times
// each value occurs in the `initialArray`
const countOfEachArrayValue = {};

initialArray.forEach((value) => {
  // Get the current count for the value
  // If `count` does not contain a number for the value, then
  // use the nullish coalescing operator default to `0`
  const currentCountForValue = countOfEachArrayValue[value] ?? 0;

  // Use the `value` as a dynamic key in the `count` object
  // Increment the currentCountForValue count by `1`
  countOfEachArrayValue[value] = currentCountForValue + 1;
});

console.log('countOfEachArrayValue: ', countOfEachArrayValue);
/* 
  countOfEachArrayValue: {
    "one": 3,
    "two": 3,
    "three": 3,
    "four": 2,
    "five": 1
  }
*/

console.log('Number of times "four" occurs: ', countOfEachArrayValue['four']);
// Number of times "four" occurs:  2

The above example creates an object, countOfEachArrayValue. As this variable's name implies, this object contains the count of each value in the array.

What if we only want to know how many times a duplicate array value occurs?

Building on the above example, we can then filter countOfEachArrayValue to only include duplicate array values.

const duplicateArrayValueCount = Object.keys(countOfEachArrayValue)
  .reduce((countOfDuplicateArrayValues, arrayValue) => {
    const isDuplicateArrayValue = countOfEachArrayValue[arrayValue] > 1;

    if (isDuplicateArrayValue) {
      return {
        ...countOfDuplicateArrayValues,
        [arrayValue]: countOfEachArrayValue[arrayValue],
      };
    }

    return countOfDuplicateArrayValues;
  }, {});

console.log('duplicateArrayValueCount: ', duplicateArrayValueCount);
// duplicateArrayValueCount:  {one: 3, two: 3, three: 3, four: 2}

Bonus - counting null, undefined, and boolean values in an array

Perhaps unexpectedly, this approach also works if our array contains null, undefined, or boolean values.

const initialArray = [
  0, 0, 0, 1, 1, 2, 2,
  true, true, false, false, false,
  null, null, null, undefined, undefined
];

const countOfEachArrayValue = {};

initialArray.forEach((value) => {
  // Get the current count for the value
  const currentCountForValue = countOfEachArrayValue[value] ?? 0;

  // Use the `value` as a dynamic key in the `count` object
  // Increment the currentCountForValue count by `1`
  countOfEachArrayValue[value] = currentCountForValue + 1;
});

console.log('countOfEachArrayValue: ', countOfEachArrayValue);
/* 
  countOfEachArrayValue: {
    "0": 3,
    "1": 2,
    "2": 2,
    "true": 2,
    "false": 3,
    "null": 3,
    "undefined": 2
  }
*/

Count duplicate values in a JavaScript array using .reduce()

Here's an alternative approach that allows us to keep a count of how many times each duplicate entry occurs within the original array.

// Array of strings with duplicate "dog" and "cat" values
const animals = ['dog', 'cat', 'dog', 'cat', 'horse', 'lamb', 'cat'];

const duplicateAnimalCount = animals.reduce((duplicateCount, animal) => {
  const firstIndexOfAnimal = animals.indexOf(animal);
  const lastIndexOfAnimal = animals.lastIndexOf(animal);
  
  // Compare the animal's first index to the last index. If the values
  // are not equal, then we can assume the animal string occurs more 
  // than once in the original `animals` array
  if (firstIndexOfAnimal !== lastIndexOfAnimal) {
    // Use filter to create an array that matches the current animal
    // eg ["dog", "dog"]
    const animalMatches = animals.filter((originalAnimal) => (
      originalAnimal === animal
    ));
    
    // Use .length to get the count for a duplicate animal
    const animalOccurances = animalMatches.length;
    
    return {
      ...duplicateCount,
      [animal]: animalOccurances
    };
  }

  return duplicateCount;
}, {});

console.log('duplicateAnimalCount: ', duplicateAnimalCount);
// duplicateAnimalCount:  { dog: 2, cat: 3 }

The above example builds on an approach detailed in my Find Duplicates in a JavaScript Array artcile. Check it out if you want to better understand how to find duplicate values in a JS array.