2010-07-14 13 views
12

Tengo dos matrices de JavaScript (A y B) que contienen objetos que he creado. Quiero comprobar que todos los objetos en el array A están contenidos en la matriz B, pero no necesariamente en el mismo orden.Conjuntos de Javascript - Comprobando dos matrices de objetos para el mismo contenido, ignorando el orden

¿Cuál es la mejor manera de hacerlo?

Editar:

Son todos los objetos reales, no primitivos, por lo que tendrá que comparar su contenido y estructura, así (tal vez usando algo como JSON.stringify).

Quiero hacer esto porque estoy aprendiendo Desarrollo basado en pruebas, y quiero probar las funciones que devuelven listas de objetos. Necesito comprobar si las listas devueltas tienen los objetos esperados o no (el orden no importa en este caso).

+2

¿Son primitivas como 'true',' false', '23' o reales objetos? ¿También puedes explicar por qué quieres hacer esto? Puede haber una mejor manera. – ChaosPandion

+0

Pregunta editada para aclaración. – Chetan

+0

¿Por qué no primero ordena y luego usa JSON.stringify para comparar – Xinus

Respuesta

2

Uso:isEqArrays(arr1, arr2)

// 
// Array comparsion 
// 

function inArray(array, el) { 
    for (var i = array.length; i--;) { 
    if (array[i] === el) return true; 
    } 
    return false; 
} 

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

¿Es esto más rápido que la solución de @ ChaosPandion? – Chetan

+0

es un navegador cruzado. Chaos no es. Él usa características de lenguaje que aún no tienen un buen soporte. – galambalazs

+1

Este código no funciona: 'isEqArrays ([0, 0, 1], [0, 1, 1])' devuelve 'true'. – callum

1

Este es probablemente el método más simple, sino el más lento.

var o = { PropA: 1, PropB: 2 }; 
var a = [1, 2, 3, 4, o]; 
var b = [2, 3, 4, 1]; 

var c = a.filter(function(value, index, obj) { 
    return b.indexOf(value) > -1; 
}); 

if (c.length !== a.length) { 
    throw new Error("Array b is missing some elements!"); 
} 

indexOf sólo se comprobará que se refieren al mismo objeto. Si desea verificar la equivalencia del valor, tendrá que hacer una comparación profunda de las propiedades o usar JSON.stringify como lo menciona en su pregunta.

+0

¿'.indexOf' también verifica la equivalencia de objeto? Como en, si hago un 'o2 = {PropA: 2, PropB: 2}' y lo pongo en 'b', ¿devolvería algo que no sea' -1'? – Chetan

+0

@Chetan - Ver actualización. – ChaosPandion

+0

Al igual que con la otra respuesta, esto devuelve un falso positivo para '[0, 1, 1]' y '[0, 0, 1]'. – callum

2

Si los duplicados también no importan, se puede hacer de una sola línea mediante el uso de lodash. Mire si la diferencia entre dos matrices está vacía.

if (_(array_1).difference(array_2).isEmpty()) { 
    // is equal ignoring order and duplicates 
} 

console.log(_([1,2,3]).difference([2,3,1]).isEmpty()) // -> true 
console.log(_([1,2,3,3]).difference([2,3,1,1]).isEmpty()) // -> also true 
Cuestiones relacionadas