2011-11-30 19 views
19

Estoy tratando de comparar dos matrices en javascript.javascript sorprendente array comparison

Lo que me gustaría es:

un < b ⇔ ∃ i ≥ 0 S.T. a [i] < b [i] y & forall; 0 ≤ j < i, a [j] = b [j]

Así matrices de trabajo número no negativo como se desee:

firebug> [0,1,2,3,4] < [1,0,0] 
true 

y la comparación de los números negativos con cero funciona como se espera:

firebug> [-1, 1] < [0, 0] 
true 

Pero la comparación de los números negativos con números negativos es ... una sorpresa:

firebug> [-2] < [-1] 
false 
firebug> -2 < -1 
true 

¿Qué está pasando aquí, entonces puedo corregir mi intuición para qué comparación de matriz significa en javascript?

+0

Véase también [¿Cómo se comparan los arrays en JavaScript] (http: //stackoverflow.com/q/16566772/1048572) para obtener una explicación del comportamiento y [la función de comparación tripartita para matrices en Javascript] (http://stackoverflow.com/q/23881838/1048572) para una solución – Bergi

Respuesta

21

La matriz se convierte a una cadena, que se reduce a .join(), que a su vez une los elementos con una coma ()) como delimitador.

"-1,1" < "0,0" === true 

debido a que el código de carácter de - (45) es menor que el código de carácter de 0 (48).

Por otro lado,

"-2" < "-1" === false 

porque los segundos códigos de caracteres se comparan (los primeros son tanto -, por lo que no da resultado aún), y el código de caracteres para 2 (50) es más grande que el código de carácter de 1 (49), por lo que este produce false.

Se trata de una clasificación lexográfica (es decir, por códigos de caracteres) y no numérica, incluso si los elementos son números (debido a la coerción de cadena).

No se recomienda la comparación básica de matrices. Se define implícitamente como comparación de cadenas, pero esto puede arrojar resultados sorprendentes.

+0

, '+ [- 2] - + [- 1];' debería hacer el truco. – jAndy

+1

@jAndy: Lo haría, pero de nuevo solo funciona bien para arreglos de un elemento. '-2 - 1' sería un poco más claro ... – pimvdb

6

No existe una comparación de matriz de JavaScript en ninguna forma similar a la que usted describe.

Lo que está sucediendo en todos los casos es que las matrices se están convirtiendo primero en cadenas uniendo sus contenidos. Por lo tanto, la cadena "-2" es no menor que la cadena "-1", porque el carácter "2" viene después de "1" en el juego de caracteres. Del mismo modo, "-1,1" es menor que "0,0" porque el carácter "-" aparece antes que los dígitos.

Se puede ver por sí mismo que en todos los casos sus comparaciones:

array1 < array2 

obtener exactamente los mismos resultados que:

("" + array1) < ("" + array2) 

o:

array1.join(",") < array2.join(",") 
1

no pude encontrar una respuesta sobre cómo comparar realmente los arrays en Javascript y obtener resultados "esperados", por lo que aquí es el código

compareArrays = function(a, b) { 
    var elA, elB, i, len; 
    for (i = 0, len = Math.min(a.length, b.length); i < len; i++) {    
    elA = a[i], elB = b[i]; 
    if (elA > elB) return 1; 
    if (elA < elB) return -1; 
    } 
    return b.length - a.length; 
}; 

console.log(compareArrays([-2], [-1])) # -1 
console.log(compareArrays([], [])) # 0 
console.log(compareArrays([null], [undefined])) # 0 
console.log(compareArrays([1, 2, 3], [1, 2, 3, 4])) # 1 
console.log(compareArrays([0, 2], [0, 1])) # 1 
console.log(compareArrays([1], [NaN])) # 0 
console.log(compareArrays([NaN], [1])) # 0