Как узнать, имеют ли два массива одинаковые значения
у меня есть эти два массива: один заполнен информацией из запроса ajax, а другой хранит кнопки, на которые нажимает пользователь. Я использую этот код (я заполнен номерами образцов):
var array1 = [2, 4];
var array2 = [4, 2]; //It cames from the user button clicks, so it might be disordered.
array1.sort(); //Sorts both Ajax and user info.
array2.sort();
if (array1==array2) {
doSomething();
}else{
doAnotherThing();
}
но он всегда дает false
, даже если два массива одинаковы, но с разными именами. (Я проверил это в консоли JS Chrome). Итак, есть ли способ узнать, содержат ли эти два массива одно и то же? Почему это дает false
? Как я могу узнать, какие значения в первом массиве являются не во второй ли?
11 ответов:
function arraysEqual(_arr1, _arr2) { if (!Array.isArray(_arr1) || ! Array.isArray(_arr2) || _arr1.length !== _arr2.length) return false; var arr1 = _arr1.concat().sort(); var arr2 = _arr2.concat().sort(); for (var i = 0; i < arr1.length; i++) { if (arr1[i] !== arr2[i]) return false; } return true; }
обратите внимание, что это не изменяет исходные массивы в отличие от принятого ответа.
если элементы массива не являются объектами - например, если они являются числами или строками, вы можете сравнить их Соединенные строки, чтобы увидеть, имеют ли они одинаковые члены в любом порядке-
var array1= [10, 6, 19, 16, 14, 15, 2, 9, 5, 3, 4, 13, 8, 7, 1, 12, 18, 11, 20, 17]; var array2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17]; if(array1.sort().join(',')=== array2.sort().join(',')){ alert('same members'); } else alert('not a match');
Array.prototype.compare = function(testArr) { if (this.length != testArr.length) return false; for (var i = 0; i < testArr.length; i++) { if (this[i].compare) { //To test values in nested arrays if (!this[i].compare(testArr[i])) return false; } else if (this[i] !== testArr[i]) return false; } return true; } var array1 = [2, 4]; var array2 = [4, 2]; if(array1.sort().compare(array2.sort())) { doSomething(); } else { doAnotherThing(); }
может быть?
Если вы хотите проверить только если два массива имеют одинаковые значения (вне зависимости от количества вхождений и порядок каждого значения), вы можете сделать это с помощью лодашь:
_.isEmpty(_.xor(array1, array2))
короткие, простые и красивые!
почему ваш код не работает
в JavaScript примитивные типы данных и непримитивные типы данных.
для примитивных типов данных,
==
и===
проверьте, имеют ли вещи по обе стороны от баров одинаковое значение. Вот почему1 === 1
- это правда.для непримитивных типов данных, таких как массивы,
==
и===
проверка на равенство ссылок. То есть они проверяют, есть лиarr1
иarr2
это один и тот же объект. В в вашем примере два массива имеют одинаковые объекты в одном порядке, но не эквивалентны.решений
два массива,
arr1
иarr2
, имеют те же члены, если и только если:
- все
arr2
находится вarr1
и
- все
arr1
находится вarr2
так что это будет делать трюк (ES2016):
const containsAll = (arr1, arr2) => arr2.every(arr2Item => arr1.includes(arr2Item)) const sameMembers = (arr1, arr2) => containsAll(arr1, arr2) && containsAll(arr2, arr1); sameMembers(arr1, arr2); // `true`
этот второй решение с помощью подчеркивание ближе к тому, что вы пытаетесь сделать:
arr1.sort(); arr2.sort(); _.isEqual(arr1, arr2); // `true`
это работает, потому что
isEqual
проверяет "глубокое равенство", что означает, что он смотрит на больше, чем просто ссылочное равенство и сравнивает значения.решение вашего третьего вопроса
вы спросили, Как узнать, какие вещи в
arr1
не содержатся вarr2
.это сделает его (ES2015):
const arr1 = [1, 2, 3, 4]; const arr2 = [3, 2, 1]; arr1.filter(arr1Item => !arr2.includes(arr1Item)); // `[4]`
вы также можете использовать Библиотеки Underscore
difference
: способ:_.difference(arr1, arr2); // `[4]`
обновление
см. комментарий @Redu-мое решение для
sameMembers
, но то, что вы можете иметь в видуsameMembersInOrder
также известный какdeepEquals
.обновление 2
если вы не заботитесь о порядке членов массивов, ES2015+ ' s
Set
может быть лучше структура данных, чемArray
. Смотрите MDN примечания о том, как реализоватьisSuperset
иdifference
используя опасное обезьянье исправление.
проверка равенства объектов:
JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())
приведенный выше тест также работает с массивами объектов, в этом случае используйте функцию сортировки, как описано в http://www.w3schools.com/jsref/jsref_sort.asp
может быть достаточно для небольших массивов с плоскими схемами JSON.
когда вы сравниваете эти два массива, вы сравниваете объекты, которые представляют массивы, а не содержимое.
вы должны будете использовать функцию для сравнения двух. Вы можете написать свой собственный, который просто петляет, хотя один и сравнивает его с другим после проверки того, что длины одинаковы.
Если вы используете структуру прототипа, вы можете использовать пересечение метод массива, чтобы узнать, что они одинаковы (независимо от порядка):
var array1 = [1,2]; var array2 = [2,1]; if(array1.intersect(array2).length === array1.length) { alert("arrays are the same!"); }
У меня были простые целочисленные значения в игровом проекте
Имел меньшее количество значений в каждом массиве, а также нуждался в том, что исходный массив нетронут
Итак, я сделал ниже, он работал нормально. (Код отредактирован для вставки здесь)var sourceArray = [1, 2, 3]; var targetArray = [3, 2, 1]; if (sourceArray.length !== targetArray.length) { // not equal // did something return false; } var newSortedSourceArray = sourceArray.slice().sort(); var newSortedTargetArray = targetArray.slice().sort(); if (newSortedSourceArray.toString() !== newSortedTargetArray.toString()) { // MAIN CHECK // not equal // did something return false; } else { // equal // did something // continued further below } // did some more work return true;
надеюсь, что это поможет.
пожалуйста, проверьте этот ответ
var arr1= [12,18]; var arr2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17]; for(i=0;i<arr1.length;i++) { var array1=arr1[i]; for(j=0;j<arr2.length;j++) { var array2=arr2[j]; if(array1==array2) { return true; } } }
С помощью ES6
мы будем использовать Ramda по
equals
функция, но вместо этого мы можем использовать Lodash или подчеркиваниеisEqual
:const R = require('ramda'); const arraysHaveSameValues = (arr1, arr2) => R.equals( [...arr1].sort(), [...arr2].sort() )
используя spread opporator, мы избегаем мутации исходных массивов и сохраняем нашу функцию чистой.