A palindrome is a word, phrase, number, or other sequence of characters which reads the same backwards as it does forward.

I’ve come across this challenge many times, so I’ve decided to post my default solution to this particular variation.

Problem

Design an function that, given a string, returns true if the string is a palindrome and false if it is not.

Constraints

  1. The string may contain spaces and punctuation, but they are not considered when detecting palindromeness. Just ignore them.
  2. The string may contain numbers, but must contain at least one letter.
  3. Consider all alphanumeric characters. The string must be the same backwards as it is normally.
  4. When developing your algorithm, try to take performance into account.

Solution

function isPalindrome(phrase = '') {
  // must contain at least one letter.
  if (!/[A-Za-z]/i.test(phrase)) return false;
  
  const sanitized = phrase.replace(/\W/g, '') // strip spaces and punctuation
                          .toLowerCase();     // normalize
  const reverse = [...sanitized]              // break letters into array
                      .reverse()              // reverse letters
                      .join('');              // put it back into string
  return sanitized === reverse;
}

Try it

Breakdown

The function takes one argument phrase and it uses the RegEx.test method to make sure that we have at least one letter, per the requirements.

Assuming we have a phrase that has at least 1 letter, I strip all spaces and punctuation from phrase using String.replace with the regular expression (\W) which is equivalent to [^A-Za-z0–9_]. Next, we use String.toLowerCase to transform this sanitized string into its’ lower case version. This will facilitate the comparison with the original phrase.

After storing the normalized string (e.g. sanitized), I move on to reversing that string so that I can compare it with the “original”. I use the spread syntax to convert each letter into an array of letters.

I do not use String.split because the string is not split between each user-perceived character (grapheme cluster) or between each unicode character (codepoint) but between each UTF-16 codeunit.

Once I have every character in an array form, I can use the Array.reverse and Array.join methods to reverse the order of the characters and produce a string in reverse order.

Finally we can return the result of a condition that tests if the normalized version of phrase is equal to the reversed version of that normalized version.

How do you get a string to a character array in JavaScript

Updated: