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:

  1. For each word, sort its characters to create a "signature"
  2. Use a Map to group words with the same signature
  3. 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.

Updated on: 2026-03-15T23:19:00+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements