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
- The string may contain spaces and punctuation, but they are not considered when detecting palindromeness. Just ignore them.
- The string may contain numbers, but must contain at least one letter.
- Consider all alphanumeric characters. The string must be the same backwards as it is normally.
- 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;
}
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.