imprimir - Usar jQuery para comparar dos matrices de objetos JavaScript
comparar dos objetos en javascript (14)
Bueno, si quieres comparar solo el contenido de las matrices, hay una útil función jQuery $.inArray()
var arr = [11, "String #1", 14, "String #2"];
var arr_true = ["String #1", 14, "String #2", 11]; // contents are the same as arr
var arr_false = ["String #1", 14, "String #2", 16]; // contents differ
function test(arr_1, arr_2) {
var equal = arr_1.length == arr_2.length; // if array sizes mismatches, then we assume, that they are not equal
if (equal) {
$.each(arr_1, function (foo, val) {
if (!equal) return false;
if ($.inArray(val, arr_2) == -1) {
equal = false;
} else {
equal = true;
}
});
}
return equal;
}
alert(''Array contents are the same? '' + test(arr, arr_true)); //- returns true
alert(''Array contents are the same? '' + test(arr, arr_false)); //- returns false
Tengo dos matrices de objetos JavaScript que me gustaría comparar para ver si son iguales. Es posible que los objetos no estén (y probablemente no lo estén) en el mismo orden en cada matriz. Cada matriz no debe tener más de 10 objetos. Pensé que jQuery podría tener una solución elegante para este problema, pero no pude encontrar mucho en línea.
Sé que una $.each(array, function(){})
podría funcionar, pero ¿hay alguna función integrada de la que no tenga conocimiento?
Gracias.
Cambiar matriz a cadena y comparar
var arr = [1,2,3],
arr2 = [1,2,3];
console.log(arr.toString() === arr2.toString());
Convierta ambos array en string y compare
if (JSON.stringify(array1) == JSON.stringify(array2))
{
// your code here
}
El buen trazador de líneas de Sudhakar R como método global jQuery.
/**
* Compare two arrays if they are equal even if they have different order.
*
* @link https://.com/a/7726509
*/
jQuery.extend({
/**
* @param {array} a
* First array to compare.
* @param {array} b
* Second array to compare.
* @return {boolean}
* True if both arrays are equal, otherwise false.
*/
arrayCompare: function (a, b) {
return $(a).not(b).get().length === 0 && $(b).not(a).get().length === 0;
}
});
En mi caso, las matrices comparadas contienen solo números y cadenas . Esta solución funcionó para mí:
function are_arrs_equal(arr1, arr2){
return arr1.sort().toString() === arr2.sort().toString()
}
¡Probémoslo!
arr1 = [1, 2, 3, ''nik'']
arr2 = [''nik'', 3, 1, 2]
arr3 = [1, 2, 5]
console.log (are_arrs_equal(arr1, arr2)) //true
console.log (are_arrs_equal(arr1, arr3)) //false
Encontré esta discusión porque necesitaba una forma de comparar profundamente matrices y objetos. Usando los ejemplos aquí, se me ocurrió lo siguiente (dividido en 3 métodos para mayor claridad):
jQuery.extend({
compare : function (a,b) {
var obj_str = ''[object Object]'',
arr_str = ''[object Array]'',
a_type = Object.prototype.toString.apply(a),
b_type = Object.prototype.toString.apply(b);
if ( a_type !== b_type) { return false; }
else if (a_type === obj_str) {
return $.compareObject(a,b);
}
else if (a_type === arr_str) {
return $.compareArray(a,b);
}
return (a === b);
}
});
jQuery.extend({
compareArray: function (arrayA, arrayB) {
var a,b,i,a_type,b_type;
// References to each other?
if (arrayA === arrayB) { return true;}
if (arrayA.length != arrayB.length) { return false; }
// sort modifies original array
// (which are passed by reference to our method!)
// so clone the arrays before sorting
a = jQuery.extend(true, [], arrayA);
b = jQuery.extend(true, [], arrayB);
a.sort();
b.sort();
for (i = 0, l = a.length; i < l; i+=1) {
a_type = Object.prototype.toString.apply(a[i]);
b_type = Object.prototype.toString.apply(b[i]);
if (a_type !== b_type) {
return false;
}
if ($.compare(a[i],b[i]) === false) {
return false;
}
}
return true;
}
});
jQuery.extend({
compareObject : function(objA,objB) {
var i,a_type,b_type;
// Compare if they are references to each other
if (objA === objB) { return true;}
if (Object.keys(objA).length !== Object.keys(objB).length) { return false;}
for (i in objA) {
if (objA.hasOwnProperty(i)) {
if (typeof objB[i] === ''undefined'') {
return false;
}
else {
a_type = Object.prototype.toString.apply(objA[i]);
b_type = Object.prototype.toString.apply(objB[i]);
if (a_type !== b_type) {
return false;
}
}
}
if ($.compare(objA[i],objB[i]) === false){
return false;
}
}
return true;
}
});
Pruebas
var a={a : {a : 1, b: 2}},
b={a : {a : 1, b: 2}},
c={a : {a : 1, b: 3}},
d=[1,2,3],
e=[2,1,3];
console.debug(''a and b = '' + $.compare(a,b)); // a and b = true
console.debug(''b and b = '' + $.compare(b,b)); // b and b = true
console.debug(''b and c = '' + $.compare(b,c)); // b and c = false
console.debug(''c and d = '' + $.compare(c,d)); // c and d = false
console.debug(''d and e = '' + $.compare(d,e)); // d and e = true
Hay una manera fácil ...
$(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0
Si lo anterior devuelve verdadero, ambas matrices son iguales incluso si los elementos están en orden diferente.
NOTA: Esto funciona solo para las versiones de jquery <3.0.0 cuando se usan objetos JSON
Mi enfoque fue bastante diferente: allané ambas colecciones usando JSON.stringify y usé una comparación de cadenas normal para verificar la igualdad.
Es decir
var arr1 = [
{Col: ''a'', Val: 1},
{Col: ''b'', Val: 2},
{Col: ''c'', Val: 3}
];
var arr2 = [
{Col: ''x'', Val: 24},
{Col: ''y'', Val: 25},
{Col: ''z'', Val: 26}
];
if(JSON.stringify(arr1) == JSON.stringify(arr2)){
alert(''Collections are equal'');
}else{
alert(''Collections are not equal'');
}
NB: tenga en cuenta que su método supone que ambas colecciones están ordenadas de manera similar, si no, ¡le daría un resultado falso!
No creo que haya una buena forma de "jQuery" para hacer esto, pero si necesita eficiencia, mapee una de las matrices con una clave determinada (uno de los campos de objetos únicos), y luego haga una comparación al recorrer la otra matriz y comparando contra el mapa, o matriz asociativa, que acaba de construir.
Si la eficiencia no es un problema, simplemente compare cada objeto en A con cada objeto en B. Siempre y cuando | A | y | B | son pequeños, deberías estar bien.
Prueba esto
function check(c,d){
var a = c, b = d,flg = 0;
if(a.length == b.length)
{
for(var i=0;i<a.length;i++)
a[i] != b[i] ? flg++ : 0;
}
else
{
flg = 1;
}
return flg = 0;
}
Si los duplicados importan de forma tal que [1, 1, 2]
no debe ser igual a [2, 1]
pero debe ser igual a [1, 2, 1]
, aquí hay una solución de conteo de referencias:
const arrayContentsEqual = (arrayA, arrayB) => {
if (arrayA.length !== arrayB.length) {
return false}
const refCount = (function() {
const refCountMap = {};
const refCountFn = (elt, count) => {
refCountMap[elt] = (refCountMap[elt] || 0) + count}
refCountFn.isZero = () => {
for (let elt in refCountMap) {
if (refCountMap[elt] !== 0) {
return false}}
return true}
return refCountFn})()
arrayB.map(eltB => refCount(eltB, 1));
arrayA.map(eltA => refCount(eltA, -1));
return refCount.isZero()}
También encontré esto cuando busco hacer algunas comparaciones de array con jQuery. En mi caso, tenía cadenas que sabía que eran matrices:
var needle = ''apple orange'';
var haystack = ''kiwi orange banana apple plum'';
Pero me importaba si era una coincidencia completa o solo una coincidencia parcial, así que usé algo como lo siguiente, basado en la respuesta de Sudhakar R:
function compareStrings( needle, haystack ){
var needleArr = needle.split(" "),
haystackArr = haystack.split(" "),
compare = $(haystackArr).not(needleArr).get().length;
if( compare == 0 ){
return ''all'';
} else if ( compare == haystackArr.length ) {
return ''none'';
} else {
return ''partial'';
}
}
También estaba buscando esto hoy y encontré: http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256BFB0077DFFD
No sé si esa es una buena solución aunque mencionan algunas consideraciones de rendimiento tomadas en cuenta.
Me gusta la idea de un método jQuery helper. @David Prefiero que su método de comparación funcione como:
jQuery.compare(a, b)
No tiene sentido para mí estar haciendo:
$(a).compare(b)
donde a y b son matrices. Normalmente cuando $ (algo) estaría pasando una cadena de selector para trabajar con elementos DOM.
También con respecto a la clasificación y ''almacenamiento en caché'' de las matrices ordenadas:
- No creo que clasificar una vez al comienzo del método en lugar de hacerlo en todo momento a través del bucle sea ''caché''. El orden seguirá ocurriendo cada vez que llame a compare (b). Eso es solo semántica, pero ...
- for (var i = 0; t [i]; i ++) { ... este bucle termina temprano si su matriz t contiene un valor falso en alguna parte, por lo que $ ([1, 2, 3, 4]) compare ( [1, falso, 2, 3]) ¡ devuelve verdadero !
- Lo que es más importante, el método array sort () ordena la matriz en su lugar , por lo que var b = t.sort () ... no crea una copia ordenada de la matriz original, ordena la matriz original y también asigna una referencia a en b . No creo que el método de comparación tenga efectos secundarios.
Parece que lo que tenemos que hacer es copiar las matrices antes de trabajar en ellas. La mejor respuesta que pude encontrar sobre cómo hacerlo de una manera jQuery fue nada menos que por John Resig aquí en SO! ¿Cuál es la forma más eficiente de clonar un objeto en JavaScript? (ver comentarios sobre su respuesta para la versión de matriz de la receta de clonación de objetos)
En cuyo caso, creo que el código sería:
jQuery.extend({
compare: function (arrayA, arrayB) {
if (arrayA.length != arrayB.length) { return false; }
// sort modifies original array
// (which are passed by reference to our method!)
// so clone the arrays before sorting
var a = jQuery.extend(true, [], arrayA);
var b = jQuery.extend(true, [], arrayB);
a.sort();
b.sort();
for (var i = 0, l = a.length; i < l; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
});
var a = [1, 2, 3];
var b = [2, 3, 4];
var c = [3, 4, 2];
jQuery.compare(a, b);
// false
jQuery.compare(b, c);
// true
// c is still unsorted [3, 4, 2]
var arr1 = [
{name: ''a'', Val: 1},
{name: ''b'', Val: 2},
{name: ''c'', Val: 3}
];
var arr2 = [
{name: ''c'', Val: 3},
{name: ''x'', Val: 4},
{name: ''y'', Val: 5},
{name: ''z'', Val: 6}
];
var _isEqual = _.intersectionWith(arr1, arr2, _.isEqual);// common in both array
var _difference1 = _.differenceWith(arr1, arr2, _.isEqual);//difference from array1
var _difference2 = _.differenceWith(arr2, arr1, _.isEqual);//difference from array2
console.log(_isEqual);// common in both array
console.log(_difference1);//difference from array1
console.log(_difference2);//difference from array2
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>