4

I am asked to check if a string is a Palindrome. To not be case sensitive. To ignore all characters that are not letters.

My Answer

 function palindrome(str) {
  var oldStr = str.toLowerCase().replace(/\s+|\,|\.|\_|\-|\:|\(|\)|\/|\\/g,  '');

  var newStr = str.replace(/\s+|\,|\.|\_|\-|\:|\(|\)|\/|\\/g, '').split("").reverse().join("").toLowerCase();

  if ( oldStr === newStr){
    return true;
  }
  else {
    return false;
  }
}
palindrome("ininiNI");

The function is to be checked with any string possibility. Example: ("0_0 (: /-\ :) 0-0") Which according to the requirements should return true.

I could not find a better solution in JavaScript then the one above.

Is there a faster/better way than just writing out each possible character to be removed/replaced? (especially since what I wrote is far from exhaustive...)

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
Chuck
  • 248
  • 5
  • 13
  • 1
    Wrong duplicate linked, link has an Java solution. Here a JS solution I searched: https://stackoverflow.com/questions/9364400/remove-not-alphanumeric-characters-from-string-having-trouble-with-the-char – Doomenik Sep 18 '17 at 09:47
  • 1
    The regex \W takes away most of the options but not all. palindrome("_eye") still does not return True. Neither does the String example I gave above. – Chuck Sep 18 '17 at 09:50
  • @Doomenik Ah ok thanks, that answer sums it up. I need to also add \_ to take out underscores. – Chuck Sep 18 '17 at 09:56
  • @Chuck you can just use this regex: `/[^a-z]/ig` – cнŝdk Sep 18 '17 at 09:57
  • Just tried it, works great. Where could I find an explanation for what exactly [^A-Za-z0-9] means/does...? – Chuck Sep 18 '17 at 09:58
  • @Doomenik actually the `.lowerCase()` call is useless here, it can be ommitted with `/[^a-z]/ig`, the `i` flag will treat both uppercase and lowercase. – cнŝdk Sep 18 '17 at 10:02
  • @Doomenik It may look a little bit harder to understand, but it's worth of use and very powerful whne you use it ;) – cнŝdk Sep 18 '17 at 10:05
  • @Chuck This is the [`/[^a-z0-9]/ig`](https://regex101.com/r/8Ud55q/1) you will need to use, you can find [all explanations **here**](https://regex101.com/r/8Ud55q/1). – cнŝdk Sep 18 '17 at 10:11
  • @chsdk I tried ' /[^a-z0-9]/ig ', taking out ' .lowerCase()' . It didn't return true for palindrome("A man, a plan, a canal. Panama") – Chuck Sep 18 '17 at 10:15
  • Yes because the regex is used to replace all the non alphanumeric charcters, so after calling it `A` won't be chnaged to `a`. – cнŝdk Sep 18 '17 at 10:19

1 Answers1

3

There is no need to call toLowerCase() and replace() twice. You can also cut string in a half, reverse one part and then compare. That way you can speed up your function few times at least.

Optimized function may look like that:

function palindrome(str) {
  str = str.toLowerCase().replace(/[^a-z]/g, '');
  var max = str.length - 1;
  for (var i = Math.floor(max / 2); i >= 0; i--) {
    if (str[i] != str[max - i]) {
      return false;
    }
  }
  return true;
}

palindrome("inabcbani"); //true
palindrome("abcddcba"); //true
palindrome("a*#$(b)&^@%@%(*a"); //true
palindrome("abba"); //true
palindrome("abcdba"); //false

For loop will be the fastest way in my opinion as it's quick and simple. You can return false once you find first character that doesn't match.

ElChupacabra
  • 1,045
  • 10
  • 18