In the previous article, I wrote about a challenge that’s often given to programmers at a tech interview: Write a program that determines if two words are anagrams. I posted a solution in Python; check it out here. In this article, we’ll refactor the Python code and write a JavaScript implementation.
Refactoring the Python version
Looking at the code for anagram()
, it’s quite clear that it isn’t DRY (Don’t Repeat Yourself), but manifestly the opposite: WET (Write Everything Twice)!
Under the time constraints of a technical interview, you might not always have the time or cognitive bandwidth to keep your code DRY, but if you should try to do so if possible. You may find that it helps convey your algorithmic thinking more effectively to the interviewer, and that’s what you want. After all, your goal throughout the process is to prove that you can actually program.
The repeated code is the part that takes a string, sorts its characters into alphabetical order, and removes the leading space if it exists. Let’s turn that code into its own method:
def sortLetters(word): # Returns the given word with its letters sorted # into alphabetical order and with any # leading space removed. word_lowercase = word.lower() return ''.join(sorted(word_lowercase)).lstrip()
With this method defined, we can use it in anagram()
. In fact, we can nest it within anagram()
. Here’s the revision:
def anagram(first_word, second_word): # Returns True if the given words are made of the exact same characters, # ignoring capitalization and spaces. def sortLetters(word): # Returns the given word with its letters sorted # into alphabetical order and with any # leading space removed. word_lowercase = word.lower() return ''.join(sorted(word_lowercase)).lstrip() return sortLetters(first_word) == sortLetters(second_word)
Creating the sortLetters()
method doesn’t just DRY up the code, but helps the method better convey what it does. Now, what anagram()
does is very clearly conveyed by its return statement: it tells you if the first word with its letters sorted is the same as the second word with its letters sorted.
I confirmed that this refactored code works by running the tests, which show just how useful having tests is.
Implementing anagram()
in JavaScript
Here’s anagram()
in JavaScript:
function anagram(firstWord, secondWord) { function sortLetters(word) { return word .toLowerCase() .split('') .sort() .join('') .trim() } return sortLetters(firstWord) === sortLetters(secondWord) }
Note that the JavaScript version of sortLetters()
is structured slightly differently from the Python version. That’s because JavaScript’s sort()
is an array method rather than a general function like Python’s sorted()
.
In the JavaScript version of sortLetters(), I use method chaining to spell out what happens to the given word step by step:
- Convert the word to lower case
- Convert that into an array of characters
- Sort that array
- Convert that array into a string
- Remove any trailing or leading whitespace
I could’ve written sortLetters()
this way…
function sortLetters(word) { return word.toLowerCase().split('').sort().join('').trim() }
…but I find that “put each method in the chain on its own line” approach more clearly conveys what I’m trying to do:
function sortLetters(word) { return word .toLowerCase() .split('') .sort() .join('') .trim() }
Next: The Swift version!