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
Grouping words with their anagrams in JavaScript
Two words or phrases which can be made by arranging the letters of each other in a different order are called anagrams of each other, like "rat" and "tar".
We need to write a JavaScript function that takes in an array of strings that might contain some anagram strings. The function should group all the anagrams into separate subarrays and return the new array thus formed.
Problem Example
If the input array is:
const arr = ['rat', 'jar', 'tar', 'raj', 'ram', 'arm', 'mar', 'art'];
Then the output array should be:
const output = [
['rat', 'tar', 'art'],
['jar', 'raj'],
['ram', 'arm', 'mar']
];
Algorithm Approach
The key insight is that anagrams have the same characters when sorted. We can use this property to group words:
- For each word, sort its characters to create a "signature"
- Use a Map to group words with the same signature
- Return all groups as an array
Implementation
const arr = ['rat', 'jar', 'tar', 'raj', 'ram', 'arm', 'mar', 'art'];
const groupSimilarWords = (arr = []) => {
if (arr.length === 0) {
return arr;
}
const map = new Map();
for (let str of arr) {
// Create sorted signature for each word
let sorted = [...str];
sorted.sort();
sorted = sorted.join('');
// Group words by their sorted signature
if (map.has(sorted)) {
map.get(sorted).push(str);
} else {
map.set(sorted, [str]);
}
}
// Return all grouped anagrams
return [...map.values()];
};
console.log(groupSimilarWords(arr));
[ [ 'rat', 'tar', 'art' ], [ 'jar', 'raj' ], [ 'ram', 'arm', 'mar' ] ]
How It Works
Let's trace through the algorithm:
// Step-by-step demonstration
const word = 'rat';
const sorted = [...word].sort().join('');
console.log(`"${word}" becomes signature: "${sorted}"`);
const word2 = 'tar';
const sorted2 = [...word2].sort().join('');
console.log(`"${word2}" becomes signature: "${sorted2}"`);
console.log(`Same signature? ${sorted === sorted2}`);
"rat" becomes signature: "art" "tar" becomes signature: "art" Same signature? true
Alternative Implementation
Here's a more concise version using reduce:
const groupAnagrams = (words) => {
const groups = words.reduce((acc, word) => {
const key = word.split('').sort().join('');
acc[key] = acc[key] || [];
acc[key].push(word);
return acc;
}, {});
return Object.values(groups);
};
const testArray = ['eat', 'tea', 'tan', 'ate', 'nat', 'bat'];
console.log(groupAnagrams(testArray));
[ [ 'eat', 'tea', 'ate' ], [ 'tan', 'nat' ], [ 'bat' ] ]
Time and Space Complexity
- Time Complexity: O(n × m log m), where n is the number of words and m is the average length of words
- Space Complexity: O(n × m) for storing the grouped results
Conclusion
Grouping anagrams efficiently uses the principle that anagrams have identical sorted character sequences. The Map-based approach provides clean grouping with good performance for most practical use cases.
