Delete duplicate elements based on first letter – JavaScript

We need to write a JavaScript function that removes duplicate strings based on their first letter, keeping only the first occurrence of each starting letter.

For example, if we have an array like:

const arr = ['Apple', 'Jack', 'Army', 'Car', 'Jason'];

We should keep only one string for each starting letter. Since 'Apple' and 'Army' both start with 'A', we keep only 'Apple' (first occurrence). Similarly, 'Jack' and 'Jason' both start with 'J', so we keep only 'Jack'.

Problem with Direct Array Modification

The original approach has a bug - modifying an array while iterating can cause elements to be skipped. Let's see the problematic code first:

// Problematic approach - modifies array during iteration
const arr = ['Apple', 'Jack', 'Army', 'Car', 'Jason'];
const deleteSameLetterWord = arr => {
    const map = new Map();
    arr.forEach((el, ind) => {
        if(map.has(el[0])){
            arr.splice(ind, 1); // This causes index shifting issues
        } else {
            map.set(el[0], true);
        }
    });
};

Method 1: Using Filter (Recommended)

The cleanest approach is to use filter() with a Set to track seen first letters:

const arr = ['Apple', 'Jack', 'Army', 'Car', 'Jason'];

const removeDuplicatesByFirstLetter = arr => {
    const seen = new Set();
    return arr.filter(word => {
        const firstLetter = word[0].toLowerCase();
        if (seen.has(firstLetter)) {
            return false;
        }
        seen.add(firstLetter);
        return true;
    });
};

const result = removeDuplicatesByFirstLetter(arr);
console.log("Original:", arr);
console.log("Filtered:", result);
Original: [ 'Apple', 'Jack', 'Army', 'Car', 'Jason' ]
Filtered: [ 'Apple', 'Jack', 'Car' ]

Method 2: Using Reverse Iteration

If you need to modify the original array, iterate backwards to avoid index shifting issues:

const arr = ['Apple', 'Jack', 'Army', 'Car', 'Jason'];

const deleteSameLetterWord = arr => {
    const seen = new Set();
    
    // Iterate backwards to avoid index issues when splicing
    for (let i = arr.length - 1; i >= 0; i--) {
        const firstLetter = arr[i][0].toLowerCase();
        if (seen.has(firstLetter)) {
            arr.splice(i, 1);
        } else {
            seen.add(firstLetter);
        }
    }
};

deleteSameLetterWord(arr);
console.log("Modified array:", arr);
Modified array: [ 'Apple', 'Jack', 'Car' ]

Case-Insensitive Handling

Both methods use toLowerCase() to handle case-insensitive comparison. This ensures 'Apple' and 'army' are treated as duplicates:

const mixedCase = ['Apple', 'jack', 'army', 'Car', 'JASON'];

const removeDuplicates = arr => {
    const seen = new Set();
    return arr.filter(word => {
        const firstLetter = word[0].toLowerCase();
        if (seen.has(firstLetter)) {
            return false;
        }
        seen.add(firstLetter);
        return true;
    });
};

console.log("Result:", removeDuplicates(mixedCase));
Result: [ 'Apple', 'jack', 'Car' ]

Comparison

Method Modifies Original? Performance Readability
filter() with Set No O(n) High
Reverse iteration Yes O(n) Medium

Conclusion

Use the filter() approach for cleaner, more functional code. It avoids mutation and index shifting issues while being more readable and maintainable.

Updated on: 2026-03-15T23:18:59+05:30

175 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements