HOWTO · JavaScript

Cómo comparar dos arrays en JavaScript

Este tutorial presenta algunos métodos para comparar dos arrays en JavaScript

En esta página

El operador === de JavaScript compara los arrays por identidad, así que esa comprobación considera distintos dos arrays creados por separado aunque tengan el mismo contenido. Para comparar su contenido, define una regla para el orden y los valores de los elementos. Si son valores primitivos en el mismo orden, compara las longitudes y después cada elemento en la posición correspondiente. Usa JSON.stringify() solo si sus reglas de serialización son adecuadas para tus datos; si el orden no importa, compara copias ordenadas. Estos métodos básicos comparan los arrays y objetos anidados por referencia, no por estructura.

¿Qué significa que dos arrays sean iguales?

Primero, decide qué significa «igual» para tu tarea. Una comparación ordenada exige que ambos arrays tengan la misma longitud y que coincidan en cada índice. Una comparación que no depende del orden los trata como colecciones, pero aun así debe tener en cuenta los valores duplicados: [1, 1, 2] no equivale a [1, 2, 2] solo porque ambos contienen los mismos valores distintos.

Decide también si la igualdad de los elementos será superficial o estructural. La igualdad estricta funciona bien para comparar valores primitivos, como números y cadenas. En el caso de objetos y arrays anidados, la igualdad estricta comprueba si ambas posiciones hacen referencia al mismo objeto; no compara sus propiedades ni su contenido anidado.

Comparar arrays en orden con un bucle o Array.prototype.every()

Una función independiente evita modificar el Array.prototype integrado. Esta versión comprueba primero la longitud y luego compara los valores correspondientes con igualdad estricta. Es una comparación ordenada y superficial.

Ejecuta este ejemplo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

function arraysEqual(left, right) {
  if (left.length !== right.length) return false;
  return left.every((value, index) => value === right[index]);
}

const first = ["red", "green", "blue"];
const second = ["red", "green", "blue"];
console.log(arraysEqual(first, second));
true

La función también rechaza un valor modificado y una longitud distinta. Estas llamadas adicionales son ejemplos no ejecutados:

function arraysEqual(left, right) {
  if (left.length !== right.length) return false;
  return left.every((value, index) => value === right[index]);
}

console.log(arraysEqual(["red", "green"], ["red", "blue"]));
console.log(arraysEqual(["red", "green"], ["red", "green", "blue"]));

La primera llamada devuelve false porque los segundos elementos son distintos; la segunda devuelve false porque las longitudes no coinciden.

Un bucle for expresa la misma regla y permite personalizar la comparación en cada índice: rechazar longitudes distintas, devolver false en la primera discrepancia y devolver true cuando coinciden todas las posiciones. Array.prototype.every() es más conciso y se detiene en cuanto su función de retorno devuelve false. Omite las posiciones sin asignar de los arrays dispersos, por lo que su resultado con ellos puede diferir del de un bucle que lee cada índice. Si esa diferencia importa, usa arrays densos o define cómo tratar los huecos.

Comparar arrays con JSON.stringify()

Si los arrays contienen valores compatibles con JSON, comparar sus representaciones serializadas es conciso: JSON.stringify(left) === JSON.stringify(right). La comparación depende del orden, así que [1, 2] y [2, 1] producen resultados distintos. La serialización también sigue reglas concretas: los valores no compatibles, como undefined dentro de un array, se serializan como null, mientras que las propiedades de objetos cuyo valor es undefined se omiten. Objetos distintos con propiedades serializables equivalentes pueden producir la misma representación, pero esto no constituye una definición general de igualdad profunda. El orden de las propiedades y el comportamiento de serialización personalizado también pueden afectar al resultado. Elige este método solo cuando esas reglas se ajusten al contrato de tus datos; no lo uses como comprobación universal de igualdad ni des por hecho que es más rápido con arrays grandes.

Comparar arrays sin tener en cuenta el orden

Si el orden no importa y los elementos son valores primitivos, ordena copias superficiales y compara las posiciones resultantes. Llamar a sort() directamente sobre los datos de entrada los modificaría, así que primero crea copias con slice(). El ordenamiento predeterminado compara representaciones de texto; proporciona un comparador cuando los valores requieran otro orden, por ejemplo, si son números. Ordenar requiere trabajo adicional, y los tipos mixtos necesitan una regla de orden explícita. Las comprobaciones de longitud y de los elementos siguen teniendo en cuenta cuántas veces aparece cada valor.

Para cadenas primitivas, ordena copias y compara cada valor resultante con igualdad estricta. Este ejemplo completo, que no se ha ejecutado, muestra el resultado de la comparación y ambos arrays originales:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

function arraysHaveSameValues(left, right) {
  if (left.length !== right.length) return false;
  const sortedLeft = left.slice().sort();
  const sortedRight = right.slice().sort();
  return sortedLeft.every((value, index) => value === sortedRight[index]);
}

const left = ["pear", "apple", "pear"];
const right = ["pear", "pear", "apple"];
console.log(arraysHaveSameValues(left, right));
console.log(left);
console.log(right);

Para estos arrays, la regla de comparación devuelve true, y ordenar las copias deja ambos datos de entrada en su orden original. Ordenar las dos copias y comparar todas las posiciones también conserva la cantidad de duplicados: los arrays con distinta cantidad de un valor no coinciden. El ordenamiento predeterminado y la igualdad estricta de este ejemplo están pensados para cadenas; los tipos mixtos necesitan un comparador y una regla de igualdad adecuados para sus tipos. Para los objetos, define una clave que represente la igualdad deseada o usa una estrategia de correspondencia diseñada para esos valores; el ordenamiento predeterminado no determina si dos objetos son iguales.

Gestionar arrays y objetos anidados

Los ejemplos de comparación ordenada y de ordenamiento usan igualdad estricta para cada elemento. Por eso, dos valores creados por separado, como [{ id: 1 }], se consideran distintos en esa posición, aunque sus propiedades visibles coincidan. Lo mismo sucede con los arrays anidados. Si necesitas igualdad estructural, usa una comparación recursiva que defina el comportamiento para cada tipo compatible o una biblioteca de igualdad profunda diseñada para la aplicación. Antes de usarla, especifica cómo debe tratar fechas, mapas, conjuntos, prototipos, referencias circulares y valores numéricos especiales; distintas herramientas de igualdad profunda pueden implementar reglas diferentes.

Si sabes que los datos son compatibles con JSON, la serialización puede ofrecer una comparación estructural compacta, con las limitaciones descritas anteriormente. En los demás casos, define explícitamente la regla de igualdad y comprueba los casos relevantes para la aplicación. En la práctica, elige el método más sencillo que cumpla los requisitos de orden y semántica de los valores: every() o un bucle para valores primitivos cuyo orden importa, serialización para datos JSON con restricciones adecuadas y una estrategia deliberada de correspondencia o igualdad profunda para los demás requisitos.