Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
