Как сравнить массивы в JavaScript?

Я на самом деле считаю, что дизайн бессмыслен. Реализованные интерфейсы, как вы сказали, просто унаследованы, поэтому нет необходимости копировать и вставлять «реализует SomeInterface» в дочерние классы. Это не яснее, умнее или вообще ...

823
задан user633183 4 October 2015 в 22:21
поделиться

16 ответов

Мое решение сравнивает объекты, а не массивы. Это будет работать так же, как у Томаша, поскольку массивы являются объектами, но без предупреждения:

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;
}

Надеюсь, это поможет вам или кому-либо еще в поисках ответа.

0
ответ дан user1877408 4 October 2015 в 22:21
поделиться

Если массив простой и порядок имеет значение, поэтому эти две строки могут помочь

//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
); 

Уменьшить количество проходов по одному из массивов и возвращает «ложь», если хотя бы один элемент из «а» не является ни равно элементу 'b' Просто оберните это в функцию

0
ответ дан Serge 4 October 2015 в 22:21
поделиться

Причина в том, что тождество или строгий оператор (===) сравниваются без преобразования типов, то есть если оба значения не имеют одинаковое значение и одинаковый тип, они не будут считаться равными.

Посмотрите эту ссылку, она выведет вас из сомнений Простой способ понять, как работает оператор идентичности

0
ответ дан ludico8 4 October 2015 в 22:21
поделиться

Вот очень короткий способ сделать это

function arrEquals(arr1, arr2){
     return arr1.length == arr2.length && 
     arr1.filter(elt=>arr1.filter(e=>e===elt).length == arr2.filter(e=>e===elt).length).length == arr1.length
}
0
ответ дан Cels 4 October 2015 в 22:21
поделиться

Я верю в простой JS и с ECMAScript 2015, что приятно и просто для понимания.

var is_arrays_compare_similar = function (array1, array2) {

    let flag = true;

    if (array1.length == array2.length) {

        // check first array1 object is available in array2 index
        array1.every( array_obj => {
            if (flag) {
                if (!array2.includes(array_obj)) {
                    flag = false;
                }
            }
        });

        // then vice versa check array2 object is available in array1 index
        array2.every( array_obj => {
            if (flag) {
                if (!array1.includes(array_obj)) {
                    flag = false;
                }
            }
        });

        return flag;
    } else {
        return false;
    }

}

надеюсь, что это поможет кому-то.

0
ответ дан ArifMustafa 4 October 2015 в 22:21
поделиться

Вы можете дисквалифицировать «одинаковость», если количество элементов не совпадает или если один из элементов отсутствует в массиве другого. Вот простая функция, которая сработала для меня.

    function isSame(arr1,arr2) {
        var same=true;
        for(var i=0;i < arr1.length;i++) {
            if(!~jQuery.inArray(arr1[i],arr2) || arr1.length!=arr2.length){
                same=false;
                }
            }
        return same;
        }
-1
ответ дан David Botsko 4 October 2015 в 22:21
поделиться

Хотя верный ответ на этот вопрос правильный и хороший, предоставленный код может использовать некоторые улучшения.

Ниже приведен мой собственный код для сравнения массивов и объектов. Код является коротким и простым:

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});

Этот код поддерживает массивы, вложенные в объекты, и объекты, вложенные в массивы.

Вы можете увидеть полный набор тестов и самостоятельно протестировать код в этом репл: https://repl.it/Esfz/3

-1
ответ дан Mator 4 October 2015 в 22:21
поделиться

Если вы используете тестовый фреймворк, такой как Mocha с библиотекой утверждений Chai , вы можете использовать равенство deep для сравнения массивов.

expect(a1).to.deep.equal(a2)

Это должно возвращать истину, только если массивы имеют равные элементы с соответствующими индексами.

5
ответ дан metakermit 4 October 2015 в 22:21
поделиться

Несмотря на то, что у этого есть много ответов, один, который я считаю полезным:

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 / документы / Web / JavaScript / Справочник / Global_Objects / Set ). С другой стороны, когда вы используете этот код:

const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
console.log(newArray)

вы получите

[ 'a', 'b', 'c' ]

В этом разница, первый даст мне набор, он будет работать как Я мог бы получить размер этого набора, но последний дает мне массив, который мне нужен, что больше относится к разрешению.

11
ответ дан Jeferson Euclides 4 October 2015 в 22:21
поделиться

Если они представляют собой только два массива чисел или строк, то это быстрый однострочный

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
6
ответ дан Gaizka Allende 4 October 2015 в 22:21
поделиться

Вот мое решение:

/**
 * 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 сломался;)

Для большинства массивов это все же быстрее, чем у большинства решений для сериализации. Вероятно, это самый быстрый метод сравнения массивов записей объектов.

3
ответ дан Harry 4 October 2015 в 22:21
поделиться
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)
2
ответ дан Vasanth 4 October 2015 в 22:21
поделиться

Рекурсивный & amp; работает на NESTED массивах:

function ArrEQ(a1,a2){
   return( 
        //:Are both elements arrays?
        Array.isArray(a1)&&Array.isArray(a2) 
        ?
        //:Yes: Test each entry for equality:
        a1.every((v,i)=>(ArrEQ(v,a2[i])))
        :
        //:No: Simple Comparison:
        (a1===a2)
   );;
};;

console.log( "Works With Nested Arrays:" );
console.log( ArrEQ( 
    [1,2,3,[4,5,[6,"SAME/IDENTICAL"]]],
    [1,2,3,[4,5,[6,"SAME/IDENTICAL"]]]
));;     
console.log( ArrEQ( 
    [1,2,3,[4,5,[6,"DIFFERENT:APPLES" ]]],
    [1,2,3,[4,5,[6,"DIFFERENT:ORANGES"]]]
));;  
2
ответ дан J.M.I. MADISON 4 October 2015 в 22:21
поделиться

Этот скрипт сравнивает 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
1
ответ дан Omar Elawady 4 October 2015 в 22:21
поделиться

Я знаю, что JSON.stringfy является медленным при контакте с большими наборами данных, но что при использовании шаблонных литералов?

Пример:

const a = [1, 2, 3];
const b = [1, 2, 'test'];

const a_string = `${a}`;
const b_string = `${b}`;

const result = (a === b);

console.log(result);

Учет Вашего использования ES6, конечно.

=)

0
ответ дан 22 November 2019 в 21:06
поделиться

Для массива попытки чисел

a1==''+a2

var a1 = [1,2,3];
var a2 = [1,2,3];

console.log( a1==''+a2 )
1
ответ дан 22 November 2019 в 21:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: