У меня есть два массива объектов JavaScript, которые я хотел бы сравнить, чтобы увидеть, одинаковы ли они. Объекты не могут (и, скорее всего, не будут) располагаться в одном и том же порядке в каждом массиве. В каждом массиве не должно быть более 10 объектов. Я думал, что jQuery может предложить элегантное решение этой проблемы, но мне не удалось найти много информации в Интернете.
Я знаю, что $.each(array, function(){})
может работать грубое вложенное решение, но есть ли встроенная функция, о которой я не знаю?
Спасибо.
[0,1] == {0:0,1:1,length=2}
$(arr1).not(arr2).length == 0
не хватает?not
это функция фильтра, а не функция равенства. Попробуйте с помощью[1,2]
и[1]
. В одном порядке вы получите[]
, а в другом - получите[2]
.not
больше не работает с универсальными объектами, начиная с версии 3.0.0-rc1. См. Github.com/jquery/jquery/issues/3147Я тоже сегодня это искал и нашел: http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256BFB0077DFFD
Не знаю, хорошее ли это решение, хотя они упоминают некоторые соображения производительности, которые принимаются во внимание.
Мне нравится идея вспомогательного метода jQuery. @David Я бы предпочел, чтобы ваш метод сравнения работал так:
Для меня нет смысла делать:
где a и b - массивы. Обычно, когда вы $ (что-то), вы передаете строку селектора для работы с элементами DOM.
Также относительно сортировки и «кеширования» отсортированных массивов:
Похоже, нам нужно скопировать массивы, прежде чем работать с ними. Лучший ответ, который я смог найти, как это сделать с помощью jQuery, был дан не кем иным, как John Resig здесь, на SO! Каков наиболее эффективный способ глубокого клонирования объекта в JavaScript? (см. комментарии к его ответу для версии массива рецепта клонирования объекта)
В этом случае я думаю, что код для этого будет:
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]
источник
Мой подход был совершенно другим - я выровнял обе коллекции с помощью JSON.stringify и использовал обычное сравнение строк для проверки равенства.
Т.е.
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: Обратите внимание, что его метод предполагает, что обе Коллекции отсортированы одинаково, в противном случае это даст вам ложный результат!
источник
Преобразуйте оба массива в строку и сравните
if (JSON.stringify(array1) == JSON.stringify(array2)) { // your code here }
источник
Я нашел это обсуждение, потому что мне нужен был способ глубокого сравнения массивов и объектов. Используя приведенные здесь примеры, я пришел к следующему (разбитому на 3 метода для ясности):
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; } });
Тестирование
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
источник
В моем случае сравниваемые массивы содержат только числа и строки . Это решение сработало для меня:
function are_arrs_equal(arr1, arr2){ return arr1.sort().toString() === arr2.sort().toString() }
Давай проверим!
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
источник
Я не думаю, что есть хороший способ "jQuery" для этого, но если вам нужна эффективность, сопоставьте один из массивов определенным ключом (одно из уникальных полей объекта), а затем проведите сравнение, перебирая другой массив. и сравнивая с картой или ассоциативным массивом, который вы только что построили.
Если эффективность не является проблемой, просто сравните каждый объект в A с каждым объектом в B. Пока | A | и | B | маленькие, все должно быть в порядке.
источник
Что ж, если вы хотите сравнивать только содержимое массивов, есть полезная функция 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
источник
Измените массив на строку и сравните
var arr = [1,2,3], arr2 = [1,2,3]; console.log(arr.toString() === arr2.toString());
источник
Хороший лайнер от Sudhakar R как глобальный метод jQuery.
/** * Compare two arrays if they are equal even if they have different order. * * @link https://stackoverflow.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; } });
источник
Я также обнаружил это, когда хотел провести сравнение массивов с помощью jQuery. В моем случае у меня были строки, которые, как я знал, были массивами:
var needle = 'apple orange'; var haystack = 'kiwi orange banana apple plum';
Но меня волновало, было ли это полное совпадение или только частичное совпадение, поэтому я использовал что-то вроде следующего, основанное на ответе Судхакара Р.
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'; } }
источник
Если дубликаты имеют такое значение, которое
[1, 1, 2]
не должно быть равно,[2, 1]
но должно быть равным[1, 2, 1]
, вот решение для подсчета ссылок: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()}
Вот скрипка, с которой можно поиграть .
источник
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>
источник
Попробуй это
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; }
источник