Confronto tra matrici di oggetti in JavaScript

Voglio confrontare 2 matrici di oggetti nel codice JavaScript. Gli oggetti hanno 8 proprietà totali, ma ogni object non avrà un valore per ciascuno, e gli array non saranno mai più grandi di 8 elementi ciascuno, quindi forse il metodo di forza bruta di attraversare ciascuno e quindi guardando i valori del 8 proprietà è il modo più semplice per fare ciò che voglio fare, ma prima di implementarle volevo vedere se qualcuno avesse una soluzione più elegante. qualche idea?

EDIT: non è ansible sovraccaricare gli operatori nelle implementazioni correnti e comuni basate su browser degli interpreti JavaScript.

Per rispondere alla domanda originale, un modo in cui puoi farlo, e ti dispiace, questo è un po ‘un trucco, semplicemente serializza i due array in JSON e poi confronta le due stringhe JSON. Questo ti dirà semplicemente se gli array sono diversi, ovviamente potresti farlo anche a ciascuno degli oggetti all’interno degli array per vedere quali erano diversi.

Un’altra opzione è quella di utilizzare una libreria che ha alcune buone funzionalità per confrontare gli oggetti: io uso e raccomando MochiKit .


EDIT: Anche la risposta kamens ha meritato considerazione, dal momento che una singola funzione per confrontare due oggetti dati sarebbe molto più piccola di qualsiasi libreria per fare ciò che suggerisco (anche se il mio suggerimento funzionerebbe certamente abbastanza bene).

Ecco un’implementazione ingenua che potrebbe fare abbastanza per voi – essere consapevoli che ci sono potenziali problemi con questa implementazione:

function objectsAreSame(x, y) { var objectsAreSame = true; for(var propertyName in x) { if(x[propertyName] !== y[propertyName]) { objectsAreSame = false; break; } } return objectsAreSame; } 

L’assunto è che entrambi gli oggetti abbiano la stessa lista esatta di proprietà.

Oh, ed è probabilmente ovvio che, nel bene o nel male, appartengo al campo di un solo punto di ritorno. 🙂

So che questa è una vecchia domanda e le risposte fornite funzionano bene … ma questo è un po ‘più breve e non richiede alcuna libreria aggiuntiva (es. JSON):

 function arraysAreEqual(ary1,ary2){ return (ary1.join('') == ary2.join('')); } 

Onestamente, con 8 oggetti max e 8 proprietà max per object, la soluzione migliore è semplicemente attraversare ogni object e fare i confronti direttamente. Sarà veloce e sarà facile.

Se utilizzerai spesso questi tipi di confronti, allora sono d’accordo con Jason sulla serializzazione JSON … ma altrimenti non è necessario rallentare la tua app con una nuova libreria o codice di serializzazione JSON.

Ho lavorato un po ‘su un semplice algoritmo per confrontare il contenuto di due oggetti e restituire un elenco comprensibile di differenza. Ho pensato di condividere. Prende in prestito alcune idee per jQuery, vale a dire l’implementazione della funzione map e il controllo del tipo di object e array.

Restituisce una lista di “oggetti diff”, che sono matrici con le informazioni diff. È molto semplice.

Ecco qui:

 // compare contents of two objects and return a list of differences // returns an array where each element is also an array in the form: // [accessor, diffType, leftValue, rightValue ] // // diffType is one of the following: // value: when primitive values at that index are different // undefined: when values in that index exist in one object but don't in // another; one of the values is always undefined // null: when a value in that index is null or undefined; values are // expressed as boolean values, indicated wheter they were nulls // type: when values in that index are of different types; values are // expressed as types // length: when arrays in that index are of different length; values are // the lengths of the arrays // function DiffObjects(o1, o2) { // choose a map() impl. // you may use $.map from jQuery if you wish var map = Array.prototype.map? function(a) { return Array.prototype.map.apply(a, Array.prototype.slice.call(arguments, 1)); } : function(a, f) { var ret = new Array(a.length), value; for ( var i = 0, length = a.length; i < length; i++ ) ret[i] = f(a[i], i); return ret.concat(); }; // shorthand for push impl. var push = Array.prototype.push; // check for null/undefined values if ((o1 == null) || (o2 == null)) { if (o1 != o2) return [["", "null", o1!=null, o2!=null]]; return undefined; // both null } // compare types if ((o1.constructor != o2.constructor) || (typeof o1 != typeof o2)) { return [["", "type", Object.prototype.toString.call(o1), Object.prototype.toString.call(o2) ]]; // different type } // compare arrays if (Object.prototype.toString.call(o1) == "[object Array]") { if (o1.length != o2.length) { return [["", "length", o1.length, o2.length]]; // different length } var diff =[]; for (var i=0; i 

Provi questo, per favore:

 function used_to_compare_two_arrays(a, b) { // This block will make the array of indexed that array b contains a elements var c = a.filter(function(value, index, obj) { return b.indexOf(value) > -1; }); // This is used for making comparison that both have same length if no condition go wrong if (c.length !== a.length) { return 0; } else{ return 1; } } 

Ecco il mio tentativo, usando il modulo di asserzione del nodo + npm package object-hash .

Suppongo che vorreste verificare se due array contengono gli stessi oggetti, anche se questi oggetti sono ordinati in modo diverso tra i due array.

 var assert = require('assert'); var hash = require('object-hash'); var obj1 = {a: 1, b: 2, c: 333}, obj2 = {b: 2, a: 1, c: 444}, obj3 = {b: "AAA", c: 555}, obj4 = {c: 555, b: "AAA"}; var array1 = [obj1, obj2, obj3, obj4]; var array2 = [obj3, obj2, obj4, obj1]; // [obj3, obj3, obj2, obj1] should work as well // calling assert.deepEquals(array1, array2) at this point FAILS (throws an AssertionError) // even if array1 and array2 contain the same objects in different order, // because array1[0].c !== array2[0].c // sort objects in arrays by their hashes, so that if the arrays are identical, // their objects can be compared in the same order, one by one var array1 = sortArrayOnHash(array1); var array2 = sortArrayOnHash(array2); // then, this should output "PASS" try { assert.deepEqual(array1, array2); console.log("PASS"); } catch (e) { console.log("FAIL"); console.log(e); } // You could define as well something like Array.prototype.sortOnHash()... function sortArrayOnHash(array) { return array.sort(function(a, b) { return hash(a) > hash(b); }); } 

La funzione objectsAreSame menzionata nella risposta di @ JasonBunting funziona bene per me. Tuttavia, c’è un piccolo problema: se x[propertyName] e y[propertyName] sono oggetti ( typeof x[propertyName] == 'object' ), dovrai chiamare la funzione in modo ricorsivo per confrontarli.