Javascript Anagram Problem

This is the anagram problem I reviewed using Stephen Grider’s interview prep on Udemy.

Amagram: a word, phrase or name formed by rearranging the letters of another, such as cinema from iceman (Google Dictionary).

The challenge is to compare two sets of words or phrases to see if they contain the same number of each letter.

Option 1 – Character Map

Helper functionbuildCharMap – First I create a helper function (buildCharMap) that builds a character map in the form of an object.  I use the regular expression (regexp) literal with the replace() method to remove punctuation etc., leaving only letters “replace(/[^\w]/g,”)”, then I add “.toLowerCase” on the end of it to convert all the letters to lower case.  The next line “charMap[char] = charMap[char] +1 || 1” adds 1 to an existing character or (||) assigns 1 if that character does not yet exist in the charMap.

Main functionanagrams – first I create character maps (aCharMap and bCharMap) based on function parameters stringA and stringB using the buildCharMap helper function.  Then I use the Object.keys() method to determine the length of the character map.  If the maps are different in length, then it can’t be an anagram and so the program returns false.

I loop through to compare both character maps.  Since I am looping through an object, I have to use the for…if loop (I would use a for…of loop for strings and arrays).  The function loops through to compare elements.  If it comes across something that is different, it returns false.  If the loop completes without detecting any different characters, I have a “return true” statement just outside the for…in loop — meaning that it was an anagram.

// OPTION 1 - CHARACTER MAP
function anagrams(stringA, stringB) {

   const aCharMap = buildCharMap(stringA);
   const bCharMap = buildCharMap(stringB);

   if (Object.keys(aCharMap).length !== Object.keys(bCharMap).length) {
      return false;
   }
   for (let char in aCharMap) {
      if(aCharMap[char] !== bCharMap[char]) {
         return false;
      }
   }
   return true;
}

function buildCharMap(str) {
   const charMap = {};

   for (let char of str.replace(/[^\w]/g,'').toLowerCase()) {
      charMap[char] = charMap[char] + 1 || 1;
   }
   return charMap;
}

Option 2 – using the sort() method.  This alternative uses a helper function to clean up the strings and then compare them.

Helper functioncleanString – first I use a regular expression literal with replace (as in option 1 above) to remove punctuation, etc.  Then I use the .toLowerCase() method to convert all letters to lower case.  Next I want to use the sort() method. Since it only works on arrays, I first need to use the split() method to convert the string into an array.  I then use sort() on the array and then the join() method to convert the array back into a string.

Main functionanagrams – this is very simple.  I call the helper function cleanString on parameters stringA to stringB to compare them and return either true or false.

This is pretty straightforward.  I still find the regular expression syntax a bit confusing.  I write these blog posts mainly for myself as a way to help internalize the material I am studying.  I’ll plan on writing a blog post on the regexp for myself and hopefully for anyone who might find it interesting.

// OPTION 2
function anagrams(stringA,stringB) {
   return cleanString(stringA) === cleanString(stringB)

}

function cleanString(str) {
   return str
      .replace(/[^\w]/g,'')
      .toLowerCase()
      .split('')
      .sort()
      .join('');
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *