Используя lodash для сравнения массивов (предметы существуют без ордера)
Я знаю, что могу сделать это с помощью циклов, но я пытаюсь найти элегантный способ сделать это:
У меня есть два массива:
var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
Я хочу использовать lodash для подтверждения того, что оба одинаковы. Под "тем же" я подразумеваю, что в массиве 1 нет элемента, который не содержится в массиве2.
В терминах проверки равенства между этими элементами:
['a', 'b'] == ['b', 'a']
или
['a', 'b'] == ['a', 'b']
оба работают, поскольку буквы всегда будут в порядке.
Спасибо заранее.
Ответы
Ответ 1
Если вы сортируете внешний массив, вы можете использовать _.isEqual()
, поскольку внутренний массив уже отсортирован.
var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
_.isEqual(array1.sort(), array2.sort()); //true
Обратите внимание, что .sort()
будет мутировать массивы. Если это проблема для вас, сначала сделайте копию, используя (например) .slice()
или оператор распространения (...
).
Или сделайте так, как рекомендует Даниэль Будик в комментарии ниже:
_.isEqual(_.sortBy(array1), _.sortBy(array2))
Lodash sortBy()
не будет изменять массив.
Ответ 2
Вы можете использовать lodashs xor
для этого
doArraysContainSameElements = _.xor(arr1, arr2).length === 0
Ответ 3
Под "тем же" я имею в виду, что в массиве 1 нет элемента, который не содержится в массиве.
Для этого вы можете использовать flatten() и difference(), который хорошо работает, если вам все равно, есть ли элементы в array2
, которые не находятся в array1
. Похоже, вы спрашиваете: array1 подмножество array2?
var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
function isSubset(source, target) {
return !_.difference(_.flatten(source), _.flatten(target)).length;
}
isSubset(array1, array2); // → true
array1.push('d');
isSubset(array1, array2); // → false
isSubset(array2, array1); // → true
Ответ 4
Я знаю, что вы не хотели повторяться, но это довольно простая IMO
const arr1 = ["a", "b"];
const arr2 = ["b", "a"];
const equal = arr1.every(item => arr2.includes(item));
console.log(equal)
// true
Ответ 5
Мы можем использовать функцию _.difference
, чтобы увидеть, есть ли разница или нет.
function isSame(arrayOne, arrayTwo) {
var a = arrayOne,
b = arrayTwo;
if (arrayOne.length <= arrayTwo.length) {
a = arrayTwo;
b = arrayOne;
return _.isEmpty(_.difference(a.sort(), b.sort()));
} else {
return false;
}
}
// examples
console.log(isSame([1, 2, 3], [1, 2, 3])); // true
console.log(isSame([1, 2, 4], [1, 2, 3])); // false
console.log(isSame([1, 2], [2, 3, 1])); // false
console.log(isSame([2, 3, 1], [1, 2])); // false
Я надеюсь, что это поможет вам.
Ответ 6
PURE JS (работает также, когда массивы и подмассивы имеют более 2 элементов в произвольном порядке). Если строка содержит ,
, используйте в качестве символа параметра join('-')
(может быть utf), который не используется в строках
array1.map(x=>x.sort()).sort().join() === array2.map(x=>x.sort()).sort().join()
var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['b', 'a']];
var r = array1.map(x=>x.sort()).sort().join() === array2.map(x=>x.sort()).sort().join();
console.log(r);
Ответ 7
Здесь уже есть ответы, но здесь моя чистая реализация JS. Я не уверен, что он оптимален, но он прозрачен, удобочитаем и прост.
// Does array a contain elements of array b?
const contains = (a, b) => new Set([...a, ...b]).size === a.length
const isEqualSet = (a, b) => contains(a, b) && contains(b, a)
Обоснование в contains()
состоит в том, что если a
содержит все элементы b
, то помещение их в один и тот же набор не приведет к изменению размера.
Например, если const a = [1,2,3,4]
и const b = [1,2]
, то new Set([...a, ...b]) === {1,2,3,4}
. Как видите, результирующий набор имеет те же элементы, что и a
.
Оттуда, чтобы сделать его более кратким, мы можем свести его к следующему:
const isEqualSet = (a, b) => {
const unionSize = new Set([...a, ...b])
return unionSize === a.length && unionSize === b.length
}