Comprobar si una cadena es anagrama de otra en Javascript

Introducción

Un anagrama es una palabra o frase que resulta de la transposición de letras de otra palabra o frase. Dicho de otra forma, una palabra es anagrama de otra si las dos tienen las mismas letras, con el mismo número de apariciones, pero en un orden diferente.

Aquí algunos ejemplos:

  • Desamparador – desparramado
  • Conservadora – conversadora
  • Nacionalista – altisonancia

Veamos cómo podemos comprobar si es un anagrama utilizando Javascript.

Comprobar si es anagrama en JS

Recordemos, primero, algunas reglas.

Reglas

  • Ambas palabras deben tener la misma longitud.
  • No se debe distinguir entre mayúsculas y minúsculas. Nacionalista es un anagrama de  Altisonancia, aunque en el primer caso la N sea mayúscula y en el segundo la A.
  • Cada letra de la primera palabra debe estar en la segunda.

Solución

Sabiendo las reglas de arriba, escribimos una función que queda así. Estamos utilizando algunas características de ES6. Abajo está el mismo código escrito para una versión anterior de Javascript.

const esAnagrama = (palabra, posibleAnagrama) => 
  palabra.toLowerCase().split("").sort().join("") === posibleAnagrama.toLowerCase().split("").sort().join("");

Con una versión anterior de Javascript, queda así:

function esAnagrama(palabra, posibleAnagrama){
  return palabra.toLowerCase().split("").sort().join("") === posibleAnagrama.toLowerCase().split("").sort().join("");
}

Explicación

Si partimos el código a su máxima expresión, se vería así:

function esAnagrama(palabra, posibleAnagrama){
  // Cambiar a minúsculas ambas cadenas
  palabra = palabra.toLowerCase();
  posibleAnagrama = posibleAnagrama.toLowerCase();
  
  // Convertir ambas cadenas en un arreglo
  palabra = palabra.split("");
  posibleAnagrama = posibleAnagrama.split("");
  
  // Ordenar ese arreglo
  palabra = palabra.sort();
  posibleAnagrama = posibleAnagrama.sort();
  
  // Una vez ordenados, los convertimos a cadena nuevamente
  palabra = palabra.join("");
  posibleAnagrama = posibleAnagrama.join("");
  
  // Finalmente comparamos
  
  if(palabra === posibleAnagrama){
    return true;
  }else{
    return false;
  }
}

Hagamos algo que yo llamo caso de uso. Supongamos que palabra = “Nacionalista” y posibleAnagrama es “Altisonancia”. Veamos lo que pasaría…

Convertimos a minúsculas

Ahora, palabra es nacionalista posibleAnagrama es altisonancia.

Pasar a arreglo

En este caso, palabra es [“n”, “a”, “c”, “i”, “o”, “n”, “a”, “l”, “i”, “s”, “t”, “a”] y posibleAnagrama es [“a”, “l”, “t”, “i”, “s”, “o”, “n”, “a”, “n”, “c”, “i”, “a”].

Ordenar

Lo ordenamos sin indicarle cómo, pero por defecto ordenará nuestras letras en orden lexicográfico. Es como ordenarlas según el alfabeto.

Ahora palabra es [“a”, “a”, “a”, “c”, “i”, “i”, “l”, “n”, “n”, “o”, “s”, “t”] y posibleAnagrama es [“a”, “a”, “a”, “c”, “i”, “i”, “l”, “n”, “n”, “o”, “s”, “t”].

Unir  y comparar

Unimos el arreglo para convertirlo a cadena; por lo que palabra es aaaciilnnost y posibleAnagrama es aaaciilnnost. Finalmente comparamos si ambas cadenas son iguales.

En caso de que una palabra tuviera menos o más letras, se evaluarían como cadenas distintas. Lo mismo pasaría si midieran lo mismo pero no tuvieran exactamente las mismas letras.

Probando

Aquí dejo algunas pruebas en un replit. Para probar utilizo este código:

function esAnagrama(palabra, posibleAnagrama){
  //Si desde un principio son iguales, regresamos false; ya que no tienen orden distinto
  if(palabra.toLowerCase() === posibleAnagrama.toLowerCase()) return false;
  
  return palabra.toLowerCase().split("").sort().join("") === posibleAnagrama.toLowerCase().split("").sort().join("");
}

var palabrasYPosiblesAnagramas = [
    {
      palabra: "Hola",
      posibleAnagrama: "Aloh"
    },
    {
      palabra: "Frase",
      posibleAnagrama: "Fresa"
    },
    {
      palabra: "Escandalizar",
      posibleAnagrama: "Zascandilear"
    },
    {
      palabra: "Conservadora",
      posibleAnagrama: "Conversadora"
    },
    {
      palabra: "Perro",
      posibleAnagrama: "Gato"
    },
    {
      palabra: "Maggie",
      posibleAnagrama: "Maggie"
    },
  ];
  
for(var x = palabrasYPosiblesAnagramas.length - 1; x >= 0; x--){
  var palabra = palabrasYPosiblesAnagramas[x].palabra,
    posibleAnagrama = palabrasYPosiblesAnagramas[x].posibleAnagrama,
    resultado = esAnagrama(palabra, posibleAnagrama);
    
  console.log("¿%s es anagrama de %s? %s", posibleAnagrama, palabra, resultado);
}

Con esta salida:

¿Maggie es anagrama de Maggie? false
¿Gato es anagrama de Perro? false
¿Conversadora es anagrama de Conservadora? true
¿Zascandilear es anagrama de Escandalizar? true
¿Fresa es anagrama de Frase? true
¿Aloh es anagrama de Hola? true

Conclusión

Ahora que leo bien la definición de anagrama, creo que tenemos un error en nuestro programa. Ya que ahí dice que es anagrama si tiene el mismo número de letras en un orden distinto.

Todo bien hasta aquí, el problema es que si llamamos a la función con “hola” y “hola” devolverá true, pero “hola” no es un anagrama de “hola” (tienen las mismas letras, pero no en diferente orden). En fin, si queremos evitar esto, podemos hacer algo así:

function esAnagrama(palabra, posibleAnagrama){
  //Si desde un principio son iguales, regresamos false; ya que no tienen orden distinto
  if(palabra.toLowerCase() === posibleAnagrama.toLowerCase()) return false;
  
  return palabra.toLowerCase().split("").sort().join("") === posibleAnagrama.toLowerCase().split("").sort().join("");
}

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *