Подтвердить что ты не робот

Как узнать, имеют ли два массива одинаковые значения

У меня есть эти два массива: один заполняется информацией из запроса 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, даже если оба массива одинаковы, но с другим именем. (Я проверил это в консоли Chrome JS). Итак, можно ли каким-либо образом узнать, содержат ли эти два массива одно и то же? Почему он дает false? Как узнать, какие значения в первом массиве находятся не во втором?

4b9b3361

Ответ 1

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;

}

Обратите внимание, что это не изменяет исходные массивы в отличие от предыдущего ответа.

Ответ 2

Если ваши элементы массива не являются объектами - например, это числа или строки, вы можете сравнить их объединенные строки, чтобы увидеть, имеют ли они одни и те же члены в любом порядке -

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

Ответ 3

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

Может быть?

Ответ 4

Если вы хотите проверить, только если два массива имеют одинаковые значения (независимо от количества вхождений и порядка каждого значения), вы можете сделать это, используя lodash:

_.isEmpty(_.xor(array1, array2))

Короткий, простой и красивый!

Ответ 5

Почему ваш код не работает

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`

Это второе решение, использующее Underscore, ближе к тому, что вы пытались сделать:

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: method:

_.difference(arr1, arr2); // `[4]`

UPDATE

См. комментарий @Redu. Мое решение для sameMembers, но вы можете иметь в виду sameMembersInOrder, также известный как deepEquals.

ОБНОВЛЕНИЕ 2

Если вы не заботитесь о порядке членов массивов, ES2015 + Set может быть лучшей структурой данных, чем Array. См. примечания MDN о том, как реализовать isSuperset и difference, используя опасные исправления обезьян.

Ответ 6

Проверка равенства объектов: JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())

Вышеупомянутый тест также работает с массивами объектов, в этом случае используется функция сортировки, как описано в http://www.w3schools.com/jsref/jsref_sort.asp

Может быть достаточно для небольших массивов с плоскими схемами JSON.

Ответ 7

Когда вы сравниваете эти два массива, вы сравниваете объекты, представляющие массивы, а не содержимое.

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

Ответ 8

Наша цель в основном проверить, равны ли 2 массива. Здесь множество означает математическое множество. Самая быстрая сортировка асимптотически занимает время O (nlog (n)). Вы можете сделать это асимптотически O (n) раз со структурой данных словаря. В JS словарь - это просто объект с ключами и значениями.

// assumes array elements are primitive types
function areArraysEqualSets(a1, a2) {
  let superSet = {};
  for (let i = 0; i < a1.length; i++) {
    const e = a1[i] + typeof a1[i];
    superSet[e] = 1;
  }

  for (let i = 0; i < a2.length; i++) {
    const e = a2[i] + typeof a2[i];
    if (!superSet[e]) {
      return false;
    }
    superSet[e] = 2;
  }

  for (let e in superSet) {
    if (superSet[e] === 1) {
      return false;
    }
  }

  return true;
}

Обратите внимание, что эта функция работает с массивами примитивных типов и предполагает, что a1 и a2 являются массивами

Ответ 9

Если вы используете Prototype Framework, вы можете использовать метод intersect массива, чтобы узнать, что они одинаковы ( независимо от порядка):

var array1 = [1,2];
var array2 = [2,1];

if(array1.intersect(array2).length === array1.length) {
    alert("arrays are the same!");
}

Ответ 10

У меня были простые целочисленные значения в проекте игры
Если бы меньшее количество значений в каждом массиве также нуждалось в том, что исходный массив не затронут Итак, я сделал это ниже, он работал нормально. (Код отредактирован для вставки здесь)

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;

Надеюсь, что это поможет.

Ответ 11

Использование ES6

Мы будем использовать функцию equals Ramda, но вместо этого мы можем использовать Lodash или Underscore isEqual:

const R = require('ramda');

const arraysHaveSameValues = (arr1, arr2) => R.equals( [...arr1].sort(), [...arr2].sort() )

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

Ответ 12

любезно проверьте этот ответ

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

Ответ 13

Если элементы в массиве являются примитивами (числами или одиночными символами), вы можете использовать комбинацию сравнения длин и использования наборов.

function equalArrayItems(arr1, arr2) {
  if (arr1.length !== arr2.length) return false
  const set1 = new Set(arr1)
  const set2 = new Set(arr2)
  const set3 = new Set(arr1, arr2)
  return set1.size === set3.size && set2.size === set3.size
}

Ответ 14

Отвечая через долгое время, но надеюсь, что это поможет кому-то, кто ищет простое решение и современные новички.

Теперь мы можем достичь этого, используя несколько библиотек, таких как lodash, underscore и т.д. (В настоящее время они становятся частью проекта из-за простоты, множества функций и большого использования)

Вы можете использовать пересечение из библиотеки lodash.

_.intersection(['2-1', '1'], ['2-2', '3-1', '2-1']); 
// => ['2-1']

Это будет работать для любого типа данных..