Só pra complementar, além de transformar o número em string, tem também a solução matemática. A mais comum que se vê por aí é a de construir o número inverso e comparar com o original:
// gerar o número inverso de "num" e comparar com o original
function isPalindrome(num) {
// segundo o enunciado, número negativo não é palíndromo
if (num < 0)
return false;
var n = num;
var inverso = 0;
while (n > 0) {
inverso = (10 * inverso) + (n % 10);
n = Math.floor(n / 10);
}
return num == inverso;
}
Mas na verdade dá pra otimizar, pois só precisamos ir até a metade do número:
// gera o inverso, mas só até a metade do número
function isPalindrome(n) {
// primeiro elimina os casos mais simples
if (n < 0) // segundo o enunciado, número negativo não é palíndromo
return false;
if (n < 10) // número com 1 dígito sempre é palíndromo
return true;
if (n % 10 == 0) // múltiplos de 10 nunca são palíndromos
return false;
if (n < 100) // número com 2 dígitos, compara o primeiro e segundo dígitos
return n % 10 === Math.floor(n / 10);
// para os demais, inverter o número até a metade
var inverso = 0;
while (inverso < n) {
inverso = (10 * inverso) + (n % 10);
n = Math.floor(n / 10);
}
return n == inverso || n == Math.floor(inverso / 10);
}
Primeiro eu elimino os casos mais básicos, e depois vou construindo o número inverso, mas o detalhe é que eu só vou até a metade.
Por exemplo, se o número é 1221
, primeiro eu pego o último dígito, então o inverso passa a ser 1
. Depois divido o número por 10, passando a ser 122
.
Depois pego o último dígito (2
) e adiciono ao final do inverso. Para isso, primeiro eu o multiplico por 10, então 1
passa a ser 10
, e depois somo o 2
, passando a ser 12
. Depois divido o número 122
por 10, e ele vira 12
. Com isso o loop se encerra e no final eu comparo ambos. Se forem iguais, é palíndromo.
O problema é quando a quantidade de dígitos é ímpar. Por exemplo, o número 12321. Ao final do loop, o inverso é 123
e o número é 12
, então eu preciso comparar também com o inverso dividido por 10 para descontar o último dígito.
Pode até parecer pior porque "tem mais linhas", mas dependendo do caso, pode ser mais eficiente do que transformar o número em string. Fazendo testes com o Benchmark.js (e que também está disponível no JsBench), vi que depende do caso. Para um único número, a string geralmente se sai melhor, mas em um loop verificando vários (milhões de números diferentes), a solução matemática se mostrou até duas vezes mais rápida (a que vai até a metade do número se sai bem melhor que a que gera o número inverso completo).
Claro que para poucos números pequenos, a diferença será irrisória e imperceptível, mas enfim, foi só pra constar que nem sempre a solução que parece mais simples é a "melhor", e caso seja preciso, é bom saber que existem alternativas. Converter números para string (e vice-versa) não costuma escalar tão bem quanto cálculos simples. E claro que depende dos casos de uso, se a diferença de desempenho é realmente relevante para o volume de dados, etc.