Как будто вы пытаетесь получить доступ к объекту, который является null
. Рассмотрим ниже пример:
TypeA objA;
. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException
, что имеет смысл.
См. Также этот пример:
String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
Чтобы сравнить массивы, проведите через них и сравните каждое значение:
// Warn if overriding existing method
if(Array.prototype.equals)
console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});
[1, 2, [3, 4]].equals([1, 2, [3, 2]]) === false;
[1, "2,3"].equals([1, 2, 3]) === false;
[1, 2, [3, 4]].equals([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].equals([1, 2, 1, 2]) === true;
Вы можете сказать: « Но гораздо проще сравнивать строки - нет петель ... « ну, тогда вы должны отметить, что есть циклы ARE. Первый рекурсивный цикл, который преобразует Array в строку и второй, который сравнивает две строки. Таким образом, этот метод быстрее, чем использование строки.
Я считаю, что большие объемы данных должны всегда храниться в массивах, а не в объектах. Однако, если вы используете объекты, их также можно частично сравнить. Вот как:
Я уже говорил выше, что два экземпляра объекта никогда не будут равными, даже если они содержат одни и те же данные на данный момент:
({a:1, foo:"bar", numberOfTheBeast: 666}) == ({a:1, foo:"bar", numberOfTheBeast: 666}) //false
У этого есть причина, поскольку в объектах могут быть, например, частные переменные.
Однако, если вы просто используете структуру объектов для хранения данных, сравнение все еще возможно:
Object.prototype.equals = function(object2) {
//For the first loop, we only check for types
for (propName in this) {
//Check for inherited methods and properties - like .equals itself
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
//Return false if the return value is different
if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
return false;
}
//Check instance type
else if (typeof this[propName] != typeof object2[propName]) {
//Different types => not equal
return false;
}
}
//Now a deeper check using other objects property names
for(propName in object2) {
//We must check instances anyway, there may be a property that only exists in object2
//I wonder, if remembering the checked values from the first loop would be faster or not
if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
return false;
}
else if (typeof this[propName] != typeof object2[propName]) {
return false;
}
//If the property is inherited, do not check any more (it must be equa if both objects inherit it)
if(!this.hasOwnProperty(propName))
continue;
//Now the detail check and recursion
//This returns the script back to the array comparing
/**REQUIRES Array.equals**/
if (this[propName] instanceof Array && object2[propName] instanceof Array) {
// recurse into the nested arrays
if (!this[propName].equals(object2[propName]))
return false;
}
else if (this[propName] instanceof Object && object2[propName] instanceof Object) {
// recurse into another objects
//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
if (!this[propName].equals(object2[propName]))
return false;
}
//Normal value comparison for strings and numbers
else if(this[propName] != object2[propName]) {
return false;
}
}
//If everything passed, let's say YES
return true;
}
Однако помните, что этот метод служит для сравнения JSON как данных, а не экземпляров классов и других вещей. Если вы хотите сравнить более сложные объекты, посмотрите на этот ответ, и это суперлайновая функция . Чтобы выполнить эту работу с Array.equals
, вы должны немного отредактировать исходную функцию:
...
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
/**REQUIRES OBJECT COMPARE**/
else if (this[i] instanceof Object && array[i] instanceof Object) {
// recurse into another objects
//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
...
Я сделал маленький тестовый инструмент для обеих функций .
indexOf
и contains
Сэмю Бенчифеф подготовил полезные функции для случая, когда вы ищете определенный объект во вложенных массивах , которые доступны здесь: https://jsfiddle.net/SamyBencherif/8352y6yw/
Хотя это работает только для скалярных массивов (см. примечание ниже), оно короткое:
array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})
Rr, в ECMAScript 6 / CoffeeScript / TypeScript со стрелочными функциями:
array1.length === array2.length && array1.every((value, index) => value === array2[index])
(Примечание: здесь «скаляр» означает значения, которые можно напрямую сравнивать с помощью ===
. Итак: числа, строки, объекты по ссылке, функции по ссылке. Подробнее см. в ссылке MDN для получения дополнительной информации о операторах сравнения).
UPDATE
Из того, что я прочитал из комментариев, сортировка массива и сравнение могут дать точный результат:
array1.length === array2.length && array1.sort().every(function(value, index) { return value === array2.sort()[index]});
Например :
array1 = [2,3,1,4];
array2 = [1,2,3,4];
Тогда приведенный выше код даст true
a1.length==a2.length && a1.every((v,i)=>a2.includes(v))
: var a1 =[1,2,3], a2 = [3,2,1];
(var a1 =[1,3,3], a2 = [1,1,3];
не будет работать должным образом)
– mems
21 November 2016 в 16:25
Сравнение 2 массивов:
var arr1 = [1,2,3];
var arr2 = [1,2,3];
function compare(arr1,arr2)
{
if((arr1 == arr2) && (arr1.length == arr2.length))
return true;
else
return false;
}
вызывающая функция
var isBool = compare(arr1.sort().join(),arr2.sort().join());
Мне нравится использовать библиотеку Underscore для проектов тяжелого кодирования массива / объекта ... в Underscore и Lodash, сравниваете ли вы массивы или объекты, как это выглядит:
_.isEqual(array1, array2) // returns a boolean
_.isEqual(object1, object2) // returns a boolean
_.isEqual([1,2,3], [2,1,3]) => false
– Vitaliy Alekask
18 August 2015 в 13:23
isEqual
, вы всегда можете использовать модуль lodash.isequal
– hellatan
18 February 2016 в 16:36
_.isEqual([1,2,3].sort(), [2,1,3].sort()) => true
– Filype
2 June 2017 в 11:30
Эта функция сравнивает два массива произвольной формы и dimesionality:
function equals(a1, a2) {
if (!Array.isArray(a1) || !Array.isArray(a2)) {
throw new Error("Arguments to function equals(a1, a2) must be arrays.");
}
if (a1.length !== a2.length) {
return false;
}
for (var i=0; i<a1.length; i++) {
if (Array.isArray(a1[i]) && Array.isArray(a2[i])) {
if (equals(a1[i], a2[i])) {
continue;
} else {
return false;
}
} else {
if (a1[i] !== a2[i]) {
return false;
}
}
}
return true;
}
В духе оригинального вопроса:
Я бы хотел сравнить два массива ... идеально, эффективно.
Я выполнял тесты производительности на некоторые из более простых предложений, предложенных здесь, со следующими результатами (быстрый до медленного):
, а (67%) - Tim Down
var i = a1.length; while (i--) { if (a1[i] !== a2[i]) return false; } return true
каждый (69 %) пользователем2782196
a1.every((v,i)=> v === a2[i]);
уменьшить (74%) с помощью DEI
a1.reduce((a, b) => a && a2.includes(b), true);
join & amp; toString (78%) Gaizka Allende & amp; vivek
a1.join('') === a2.join(''); a1.toString() === a2.toString();
half toString (90%) от Victor Palomo
a1 == a2.toString();
stringify (100%) на radtek
JSON.stringify(a1) === JSON.stringify(a2);
Обратите внимание, что приведенные ниже примеры предполагают, что массивы отсортированы, одномерные массивы. Сравнение
.length
было удалено для общего теста (добавьтеa1.length === a2.length
к любому из предложений, и вы получите повышение производительности на 10%). Выберите любые решения, которые лучше всего подходят для вас, зная скорость и ограничение каждого из них.Несвязанное примечание: интересно видеть, как люди получают все триггер-счастливые Джон Уэйнс при снижении голосов на вполне законные ответы на этот вопрос.
В тех же строках, что и JSON.encode, следует использовать join ().
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
//slice so we do not effect the original
//sort makes sure they are in order
//join makes it a string so we can do a string compare
var cA = arrA.slice().sort().join(",");
var cB = arrB.slice().sort().join(",");
return cA===cB;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"]; //will return true
console.log( checkArrays(a,b) ); //true
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //true
Проблема только в том, что вам нравятся типы, которые были проведены последними сравнительными тестами. Если вам нравятся типы, вам придется зацикливаться.
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
//slice so we do not effect the orginal
//sort makes sure they are in order
var cA = arrA.slice().sort();
var cB = arrB.slice().sort();
for(var i=0;i<cA.length;i++){
if(cA[i]!==cB[i]) return false;
}
return true;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];
console.log( checkArrays(a,b) ); //true
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //false
Если порядок должен оставаться таким же, как это просто цикл, никакой сортировки не требуется.
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
for(var i=0;i<arrA.length;i++){
if(arrA[i]!==arrB[i]) return false;
}
return true;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];
console.log( checkArrays(a,a) ); //true
console.log( checkArrays(a,b) ); //false
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //false
.join()
. Возможно, если бы вы заявили, что ваше второе решение является первичным (так как оно лучше, но беззубым против многомерных массивов), я бы не стал так вас судить. До сих пор я перебросил все ответы, которые преобразуют массивы в строки. Кроме того, я поддержал все, что использует правильный путь, если вам это нужно знать. Это означает ответ @Tim Down и Bireys one.
– Tomáš Zato
22 March 2013 в 01:01
checkArrays([1,2,3] , ["1,2",3]) == true
, и очень маловероятно, что это то, что вы хотите!
– Doin
16 October 2014 в 04:46
join()
, как это делает его тонко багги!
– Doin
17 October 2014 в 14:49
Положив ответ Томаша Зато, я согласен с тем, что простое повторение массивов является самым быстрым. Кроме того (как уже отмечали другие), функцию следует называть равной / равной, а не сравнивать. В свете этого я модифицировал функцию, чтобы обрабатывать массивы для сходства - т. Е. Они имеют одни и те же элементы, но не в порядке - для личного использования, и я думал, что я брошу его здесь для всеобщего обозрения.
Array.prototype.equals = function (array, strict) {
if (!array)
return false;
if (arguments.length == 1)
strict = true;
if (this.length != array.length)
return false;
for (var i = 0; i < this.length; i++) {
if (this[i] instanceof Array && array[i] instanceof Array) {
if (!this[i].equals(array[i], strict))
return false;
}
else if (strict && this[i] != array[i]) {
return false;
}
else if (!strict) {
return this.sort().equals(array.sort(), true);
}
}
return true;
}
Эта функция принимает дополнительный параметр strict, который по умолчанию имеет значение true. Этот строгий параметр определяет, должны ли массивы быть полностью равными как по содержимому, так и по порядку этого содержимого или просто содержать одно и то же содержимое.
Пример:
var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 4, 3]; // Loosely equal to 1
var arr3 = [2, 2, 3, 4]; // Not equal to 1
var arr4 = [1, 2, 3, 4]; // Strictly equal to 1
arr1.equals(arr2); // false
arr1.equals(arr2, false); // true
arr1.equals(arr3); // false
arr1.equals(arr3, false); // false
arr1.equals(arr4); // true
arr1.equals(arr4, false); // true
I 've также написал быстрый jsfiddle с функцией и этим примером: http://jsfiddle.net/Roundaround/DLkxX/
Если это только два массива чисел или строк, это быстрый однострочный
const array1 = [1, 2, 3];
const array2 = [1, 3, 4];
console.log(array1.join(',') === array2.join(',')) //false
const array3 = [1, 2, 3];
const array4 = [1, 2, 3];
console.log(array3.join(',') === array4.join(',')) //true
[11]
. Довольно очевидно, почему это происходит и как исправить.
– Dan M.
10 May 2017 в 02:21
Решение Herer:
/**
* Tests two data structures for equality
* @param {object} x
* @param {object} y
* @returns {boolean}
*/
var equal = function(x, y) {
if (typeof x !== typeof y) return false;
if (x instanceof Array && y instanceof Array && x.length !== y.length) return false;
if (typeof x === 'object') {
for (var p in x) if (x.hasOwnProperty(p)) {
if (typeof x[p] === 'function' && typeof y[p] === 'function') continue;
if (x[p] instanceof Array && y[p] instanceof Array && x[p].length !== y[p].length) return false;
if (typeof x[p] !== typeof y[p]) return false;
if (typeof x[p] === 'object' && typeof y[p] === 'object') { if (!equal(x[p], y[p])) return false; } else
if (x[p] !== y[p]) return false;
}
} else return x === y;
return true;
};
Работает с любой вложенной структурой данных и, очевидно, игнорирует методы объектов. Даже не думайте о расширении Object.prototype с помощью этого метода, когда я это пробовал один раз, jQuery сломался;)
Для большинства массивов он все же быстрее, чем большинство решений для сериализации. Вероятно, это самый быстрый метод сравнения для массивов записей объектов.
equal({}, {a:1})
и equal({}, null)
, и эти ошибки отсутствуют: equal({a:2}, null)
– kristianlm
3 February 2017 в 14:05
Расширение идеи Томаша Зато. Tomas Array.prototype.compare должен быть infact, называемый Array.prototype.compareIdentical.
Он проходит:
[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 2]]) === false;
[1, "2,3"].compareIdentical ([1, 2, 3]) === false;
[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].compareIdentical ([1, 2, 1, 2]) === true;
Но не работает:
[[1, 2, [3, 2]],1, 2, [3, 2]].compareIdentical([1, 2, [3, 2],[1, 2, [3, 2]]])
Здесь лучше (на мой взгляд) версия:
Array.prototype.compare = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
this.sort();
array.sort();
for (var i = 0; i < this.length; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].compare(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
Выберите каждый из [a] и пропустите все из [b]: Результат: 1, 5
var a = [1,4,5,9];
var b = [1,6,7,5];
for (i = 0; i < a.length; i++) {
for (z = 0; z < a.length; z++) {
if (a[i] === b[z]) {
console.log(b[z]); // if match > console.log it
}
}
}
Несмотря на то, что у этого есть много ответов, которые, я считаю, помогут:
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
В вопросе о том, как будет выглядеть структура массива, не сказано, поэтому, если вы точно знаете, что у вас не будет вложенных массивов или объектов в вашем массиве (это случилось со мной, поэтому я пришел к этому ответу), этот код будет работать.
Что происходит, так это то, что мы используем оператор спреда (...) для согласования обоих массивов, затем мы используем Set для устранения любых дубликатов. Если у вас есть это, вы можете сравнить их размеры, если все три массива имеют одинаковый размер, вы можете пойти.
Этот ответ также игнорирует порядок элементов, как я уже сказал, точная ситуация со мной , так что, может быть, кто-то в той же ситуации может оказаться здесь (как и я).
Edit1.
Отвечая на вопрос Дмитрия Гринько: «Почему вы использовали оператор спреда ( ...) здесь - ... новый набор? Он не работает »
Рассмотрим этот код:
const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ new Set( [...arr1, ...arr2] ) ]
console.log(newArray)
Вы получите
[ Set { 'a', 'b', 'c' } ]
Чтобы работать с этим значением, вам нужно будет использовать некоторые свойства Set (см. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set ). С другой стороны, когда вы используете этот код:
const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
console.log(newArray)
Вы получите
[ 'a', 'b', 'c' ]
В этом разница, первая даст мне набор, он будет работать так как я мог бы получить размер этого набора, но последний дает мне массив, в котором я нуждаюсь, что более прямо относится к разрешению.
JSON.stringify(collectionNames).includes(JSON.stringify(sourceNames)) ? array.push(collection[i]) : null
Вот как я это сделал.
Причина в том, что идентификатор или строгий оператор (===), он сравнивается без преобразования типа, это означает, что если оба значения не имеют одинакового значения и одного и того же типа, они не будут считаться равными.
взгляните на эту ссылку, вы не можете сомневаться , чтобы понять, как работает оператор-идентификатор
Если вы используете платформу тестирования, например Mocha , с библиотекой утверждений Chai , вы можете использовать равенство deep для сравнения массивов.
expect(a1).to.deep.equal(a2)
Это должно возвращать true, только если массивы имеют равные элементы в соответствующих индексах.
Это сравнивает два несортированных массива:
function areEqual(a, b) {
if ( a.length != b.length) {
return false;
}
return a.filter(function(i) {
return !b.includes(i);
}).length === 0;
}
этот скрипт сравнивает Object, Arrays и многомерный массив
function compare(a,b){
var primitive=['string','number','boolean'];
if(primitive.indexOf(typeof a)!==-1 && primitive.indexOf(typeof a)===primitive.indexOf(typeof b))return a===b;
if(typeof a!==typeof b || a.length!==b.length)return false;
for(i in a){
if(!compare(a[i],b[i]))return false;
}
return true;
}
. Первая строка проверяет, является ли он примитивным типом. если он сравнивает два параметра.
, если они являются объектами. он выполняет итерацию по объекту и проверяет каждый элемент рекурсивно.
Использование:
var a=[1,2,[1,2]];
var b=[1,2,[1,2]];
var isEqual=compare(a,b); //true
Мы могли бы сделать это функциональным способом, используя every
( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every )
function compareArrays(array1, array2) {
if (array1.length === array2.length)
return array1.every((a, index) => a === array2[index])
else
return false
}
// test
var a1 = [1,2,3];
var a2 = [1,2,3];
var a3 = ['a', 'r', 'r', 'a', 'y', '1']
var a4 = ['a', 'r', 'r', 'a', 'y', '2']
console.log(compareArrays(a1,a2)) // true
console.log(compareArrays(a1,a3)) // false
console.log(compareArrays(a3,a4)) // false
Я думаю, что это самый простой способ сделать это, используя JSON stringify, и это может быть лучшим решением в некоторых ситуациях:
JSON.stringify(a1) === JSON.stringify(a2);
Это преобразует объекты a1
и a2
в чтобы их можно было сравнить. Порядок очень важен в большинстве случаев, поскольку он может сортировать объект с помощью алгоритма сортировки, показанного в одном из приведенных выше ответов.
Пожалуйста, обратите внимание, что вы больше не сравниваете объект, а строковое представление объект. Это может быть не совсем то, что вы хотите.
Неясно, что вы подразумеваете под «идентичными». Например, массивы a
и b
ниже идентичны (обратите внимание на вложенные массивы)?
var a = ["foo", ["bar"]], b = ["foo", ["bar"]];
Вот оптимизированная функция сравнения массива, которая в свою очередь сравнивает соответствующие элементы каждого массива с использованием строгого равенства и не выполняет рекурсивного сравнения элементов массива, которые сами представляют собой массивы, что означает, что в приведенном выше примере arraysIdentical(a, b)
вернет false
. Он работает в общем случае, на котором решения на основе JSON- и join()
не будут:
function arraysIdentical(a, b) {
var i = a.length;
if (i != b.length) return false;
while (i--) {
if (a[i] !== b[i]) return false;
}
return true;
};
true
. Ответ объясняет, что это не так. Если вам нужно сравнить вложенные массивы, вы можете легко добавить рекурсивную проверку.
– Tim Down
31 July 2015 в 23:16
Мое решение сравнивает объекты, а не массивы. Это будет работать так же, как Tomáš as Arrays - это объекты, но без предупреждения:
Object.prototype.compare_to = function(comparable){
// Is the value being compared an object
if(comparable instanceof Object){
// Count the amount of properties in @comparable
var count_of_comparable = 0;
for(p in comparable) count_of_comparable++;
// Loop through all the properties in @this
for(property in this){
// Decrements once for every property in @this
count_of_comparable--;
// Prevents an infinite loop
if(property != "compare_to"){
// Is the property in @comparable
if(property in comparable){
// Is the property also an Object
if(this[property] instanceof Object){
// Compare the properties if yes
if(!(this[property].compare_to(comparable[property]))){
// Return false if the Object properties don't match
return false;
}
// Are the values unequal
} else if(this[property] !== comparable[property]){
// Return false if they are unequal
return false;
}
} else {
// Return false if the property is not in the object being compared
return false;
}
}
}
} else {
// Return false if the value is anything other than an object
return false;
}
// Return true if their are as many properties in the comparable object as @this
return count_of_comparable == 0;
}
Надеюсь, это поможет вам или кому-либо еще найти ответ.
var a1 = [1,2,3,6];
var a2 = [1,2,3,5];
function check(a, b) {
return (a.length != b.length) ? false :
a.every(function(row, index) {
return a[index] == b[index];
});
}
check(a1, a2);
////// ИЛИ ///////
var a1 = [1,2,3,6];
var a2 = [1,2,3,6];
function check(a, b) {
return (a.length != b.length) ? false :
!(a.some(function(row, index) {
return a[index] != b[index];
}));
}
check(a1, a2)
для одномерного массива, который вы можете просто использовать:
arr1.sort().toString() == arr2.sort().toString()
, это также позаботится о массиве с несогласованным индексом.
===
(чтобы сделать linter happy), если соответствующие массивы содержат строковые элементы.
– TranslucentCloud
31 March 2017 в 11:44
[1,2]
и ["1,2"]
. Обратите внимание, что вызов the sort()
будет изменять входные массивы i> - это может быть нежелательно.
– try-catch-finally
15 July 2017 в 08:51
function compareArrays(arrayA, arrayB) {
if (arrayA.length != arrayB.length) return true;
for (i = 0; i < arrayA.length; i++)
if (arrayB.indexOf(arrayA[i]) == -1) {
return true;
}
}
for (i = 0; i < arrayB.length; i++) {
if (arrayA.indexOf(arrayB[i]) == -1) {
return true;
}
}
return false;
}
Вот версия CoffeeScript для тех, кто предпочитает это:
Array.prototype.equals = (array) ->
return false if not array # if the other array is a falsy value, return
return false if @length isnt array.length # compare lengths - can save a lot of time
for item, index in @
if item instanceof Array and array[index] instanceof Array # Check if we have nested arrays
if not item.equals(array[index]) # recurse into the nested arrays
return false
else if this[index] != array[index]
return false # Warning - two different object instances will never be equal: {x:20} != {x:20}
true
Все кредиты передаются @ tomas-zato.
Хотя верный ответ на этот вопрос правильный и хороший, предоставленный код может использовать некоторое улучшение.
Ниже мой собственный код для сравнения массивов и объектов. Код короткий и простой:
Array.prototype.equals = function(otherArray) {
if (!otherArray || this.length != otherArray.length) return false;
return this.reduce(function(equal, item, index) {
var otherItem = otherArray[index];
var itemType = typeof item, otherItemType = typeof otherItem;
if (itemType !== otherItemType) return false;
return equal && (itemType === "object" ? item.equals(otherItem) : item === otherItem);
}, true);
};
if(!Object.prototype.keys) {
Object.prototype.keys = function() {
var a = [];
for (var key in this) {
if (this.hasOwnProperty(key)) a.push(key);
}
return a;
}
Object.defineProperty(Object.prototype, "keys", {enumerable: false});
}
Object.prototype.equals = function(otherObject) {
if (!otherObject) return false;
var object = this, objectKeys = object.keys();
if (!objectKeys.equals(otherObject.keys())) return false;
return objectKeys.reduce(function(equal, key) {
var value = object[key], otherValue = otherObject[key];
var valueType = typeof value, otherValueType = typeof otherValue;
if (valueType !== otherValueType) return false;
// this will call Array.prototype.equals for arrays and Object.prototype.equals for objects
return equal && (valueType === "object" ? value.equals(otherValue) : value === otherValue);
}, true);
}
Object.defineProperty(Object.prototype, "equals", {enumerable: false});
Этот код поддерживает массивы, вложенные в объекты и объекты, вложенные в массивы.
Вы можете увидеть полный набор тестов и протестировать сам код при этом repl: https://repl.it/Esfz/3
Если массив прост, и порядок имеет значение, поэтому две строки могут помочь
//Assume
var a = ['a','b', 'c']; var b = ['a','e', 'c'];
if(a.length !== b.length) return false;
return !a.reduce(
function(prev,next,idx, arr){ return prev || next != b[idx] },false
);
Уменьшить количество проходов по одному из массивов и возвращает «false», если хотя бы один элемент «a» равен ни равно элементу 'b' Просто оберните это в функцию
Array.prototype.reduce
будет проходить каждый элемент в a
, даже если первые сравниваемые элементы не совпадают. Кроме того, использование !a
и !=
в цикле является двойным отрицательным, что делает этот ответ более сложным (и трудно читаемым), чем нужно
– user633183
7 August 2016 в 15:39
В моем случае сравниваемые массивы содержат только числа и строки. Эта функция покажет вам, содержат ли массивы одинаковые элементы.
function are_arrs_match(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_match(arr1, arr2)) //true
console.log (are_arrs_match(arr1, arr3)) //false
are_arrs_equal([1,2], [2,1])
. Кроме того, см. Другие обсуждения на этой странице, почему сборка является ненужной, хрупкой и неправильной.
– phyzome
3 August 2016 в 03:31
are_arrs_equal([1,2], [2,1])
возвращает true
, как ожидалось. Возможно, это решение не идеально, но это сработало для меня.
– yesnik
8 August 2016 в 12:37
are_arrs_match([1,2], ["1,2"])
(возвращает true
). Обратите внимание, что вызов the sort()
будет изменять входные массивы i> - это может быть нежелательно.
– try-catch-finally
15 July 2017 в 08:38
this[i] !== array[i]
вместо!=
. – Tim S. 15 May 2013 в 14:19equals
вместоcompare
. По крайней мере, в .NET сравнение обычно возвращает подписанный int, указывающий, какой объект больше, чем другой. См. Comparer.Compare . – Oliver 31 May 2013 в 13:24