Javascript Arrays - Проверка двух массивов объектов на одинаковое содержимое, игнорируя порядок - PullRequest
13 голосов
/ 14 июля 2010

У меня есть два массива JavaScript (A и B), которые содержат созданные мной объекты.Я хочу проверить, что все объекты в массиве A содержатся в массиве B, но не обязательно в том же порядке.

Каков наилучший способ сделать это?

Редактировать:

Все они являются реальными объектами, а не примитивами, поэтому мне нужно будет сравнить их содержимое и структуру (возможно, используя что-то вроде JSON.stringify).

Я хочу сделать этопотому что я изучаю разработку через тестирование и хочу протестировать функции, которые возвращают списки объектов.Мне нужно проверить, есть ли в возвращенных списках ожидаемые объекты или нет (порядок в данном случае не имеет значения).

Ответы [ 4 ]

3 голосов
/ 03 декабря 2016

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

if (_(array).difference(otherArray).isEmpty()) {
    // is equal ignoring order and duplicates
}

console.log(_([1,2,3]).difference([2,3,1]).isEmpty()) // -> true
console.log(_([1,2,3,3]).difference([2,3,1,1]).isEmpty()) // -> also true
2 голосов
/ 14 июля 2010

Использование: isEqArrays(arr1, arr2)

//
// Array comparsion
//

function inArray(array, el) {
  for ( var i = array.length; i--; ) {
    if ( array[i] === el ) return true;
  }
  return false;
}

function isEqArrays(arr1, arr2) {
  if ( arr1.length !== arr2.length ) {
    return false;
  }
  for ( var i = arr1.length; i--; ) {
    if ( !inArray( arr2, arr1[i] ) ) {
      return false;
    }
  }
  return true;
}
1 голос
/ 07 июня 2018

С ES6 вы можете использовать все и некоторые (и длину).

let A = [1, 2, 3];
let B = [2, 3, 1];

// all objects in A are contained in B (A ⊆ B)
// you can compare a <-> b however you'd like (here just `a === b`)
let AsubB = A.every(a => B.some(b => a === b));

// A and B are the same length
let sameLength = A.length === B.length;

// their contents are as equal as previously tested:
let equal = AsubB && sameLength;
1 голос
/ 14 июля 2010

Это, вероятно, самый простой метод, если не самый медленный.

var o = { PropA: 1, PropB: 2 };
var a = [1, 2, 3, 4, o];
var b = [2, 3, 4, 1];

var c = a.filter(function(value, index, obj) {
    return b.indexOf(value) > -1;
});

if (c.length !== a.length) {
    throw new Error("Array b is missing some elements!");
}

indexOf будет проверять только то, что они ссылаются на один и тот же объект. Если вы хотите проверить эквивалентность значений, вам придется глубоко сравнить свойства или использовать JSON.stringify, как вы упомянули в своем вопросе.

...