1

I'm trying to write code to determine if a string is a palindrome. I am making the string lowercase, taking out the spaces, and turning it into an array. Next, I am splitting it in half, reversing the second half, and comparing those two arrays to see if the string is a palindrome. The function will not log true.

let string = "Never odd or even";
let lowerString = string.toLowerCase();
let split = lowerString.split("");
let array = split.filter(noSpaces);

function noSpaces(i) {
  return i !== " ";
}

function checkIfPal() {
  if (array.length % 2 === 1) {
    let firstHalf = array.slice(0, array.length / 2);
    let secondHalf = array.slice(array.length / 2 + 1, array.length);
    let revSecondHalf = [];
    for (let i = secondHalf.length - 1; i > -1; i--) {
      revSecondHalf.push(secondHalf[i]);
    }
    if (firstHalf === revSecondHalf) {
      console.log("true for odd");
    } else {
      console.log("false for odd");
    }
  } else {
    let firstHalf = array.slice(0, array.length / 2);
    let secondHalf = array.slice(array.length / 2, array.length);
    let revSecondHalf = [];
    for (let i = secondHalf.length - 1; i > -1; i--) {
      revSecondHalf.push(secondHalf[i]);
    }
    if (firstHalf === revSecondHalf) {
      console.log("true for even");
    } else {
      console.log("false for even");
    }
  }
}
checkIfPal();
  • 1
    Possible duplicate of [Check string for palindrome](https://stackoverflow.com/questions/4138827/check-string-for-palindrome) – Akrion Nov 22 '18 at 00:28
  • Why not just check if the character at `i` is equal to the one at `length - i - 1` until you reach half way? Also, "*I'm not sure what is wrong*" is not a sufficient explanation of your problem, what goes wrong? – RobG Nov 22 '18 at 00:30
  • 2
    You're trying to compare two arrays using `===` which you can't do. You need to `join` the arrays to two strings and _then_ compare them. – Andy Nov 22 '18 at 00:32
  • 1
    https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript – epascarello Nov 22 '18 at 00:35
  • One-liner for fun: `const isPalindrome = s => s.length <= 1 ? true : (s.substr(-1) === s.substr(0, 1) && isPalindrome(s.substr(1, length-2)))` You could pre-process the string to remove spaces and uppers. – spender Nov 22 '18 at 00:59
  • @spender—the whole thing can be done without recursion in a few more characters: `let isPalindrome = s => s.toLowerCase().replace(/[^a-z0-9]/g,'').split('').every((c, i, o) => c == o[o.length - ++i])`, though it does about twice as many tests as minimally required. :-) – RobG Nov 22 '18 at 09:07

5 Answers5

3

There's a much simpler way of doing this.

  1. Strip out anything that isn't a letter or number
  2. Make the string lower case
  3. Loop over half the string
  4. Compare current letter to last letter minus current position

function isPalindrome(str) {
    str = str.replace(/[^\w\d]/g, '').toLowerCase();
    const len = str.length;

    for (let i = 0; i < len / 2; i++) {
        if (str[i] !== str[len - 1 - i]) {
            return false;
        }
    }

    return true;
}

console.log(isPalindrome('A man, a plan, a canal, Panama!'));
console.log(isPalindrome('Mr. Owl Ate My Metal Worm'));
console.log(isPalindrome('A Santa Lived As a Devil At NASA'));

And then there is the super simple, but not very efficient on long strings way of doing it.

function isPalindrome(str) {
    str = str.replace(/[^\w\d]/g, '').toLowerCase();
    return str === str.split('').reverse().join('');
}

console.log(isPalindrome('A man, a plan, a canal, Panama!'));
console.log(isPalindrome('Mr. Owl Ate My Metal Worm'));
console.log(isPalindrome('A Santa Lived As a Devil At NASA'));
AnonymousSB
  • 3,516
  • 10
  • 28
0

In this line

if (firstHalf === revSecondHalf) {

you're attempting to compare two arrays, but JavaScript doesn't allow you to do that with === as they are two different objects. Either join each array to a string and then compare them, or loop over the elements in one array comparing them to the elements at the same index in the other array.

The former method is easier.

Andy
  • 61,948
  • 13
  • 68
  • 95
0

In your script you are comparing two array objects against each other using ===.

If the variables in the comparison reference the exact same array object, then this will return true. But if they point to two different array objects, even if their contents are the same, it will always return false.

If you wish to continue using the arrays for comparison, you will need to check if each element of the array is the same.

function compareArrayElements(arr1, arr2) {
    if (arr1.length != arr2.length)
        return false;
    for (var i=0;i<arr1.length;i++) {
        if (arr1[i] != arr2[i])
            return false;
    }
    return true;
}

Now that you have a solution, you can work to optimizing it and lowering the number of for loops.

samthecodingman
  • 23,122
  • 4
  • 30
  • 54
0

An algorithm based on comparing an array with its reverse:

const isPalindrome = (str) => {
  //Eliminate punctuation and spaces
  // Force lower case
  // Split
   let arr = str.toString().replace(/[^A-Za-z0-9_]/g, "").toLowerCase().split('');

  // Join into one word
  let joined = arr.join('');

  // Reverse adn join into one word
  let reverseJoined = arr.reverse().join('');

  //compare
  return joined == reverseJoined;
}

console.log(isPalindrome('Red rum, sir, is murder'));
console.log(isPalindrome(404));
console.log(isPalindrome('Red rum, sir'));
console.log(isPalindrome(500));
Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
0
"use strict";
function palindromeString(str) {
  let rev = "";
  const len = str.length;
  for (let i = len - 1; i >= 0; i--) {
    rev += str[i];
  }
  const value =
    str.toLowerCase() === rev.toLowerCase()
      ? "given word is Palindrome"
      : "given word is not Palindrome";
  return value;
}
console.log(palindromeString("Raccar"));