Как вы сравниваете два набора javascript? Я пробовал использовать ==
и, ===
но оба возвращают false.
a = new Set([1,2,3]);
b = new Set([1,3,2]);
a == b; //=> false
a === b; //=> false
Эти два набора эквивалентны, потому что по определению наборы не имеют порядка (по крайней мере, обычно). Я просмотрел документацию по Set на MDN и не нашел ничего полезного. Кто-нибудь знает, как это сделать?
javascript
set
ecmascript-6
Williamcodes
источник
источник
===
предназначен для равенства значений, а не равенства объектов.new Set([1,2,3]) != new Set([1,2,3])
. Это делает набор Javascript бесполезным для наборов наборов, поскольку надмножество будет содержать повторяющиеся подмножества. Единственный обходной путь, который приходит на ум, - это преобразование всех подмножеств в массивы, сортировка каждого массива и последующее кодирование каждого массива как строки (например, JSON).Ответы:
Попробуй это:
Более функциональный подход:
all
Функция работает для всех итерации объектов (например ,Set
иMap
).Если бы она
Array.from
получила более широкую поддержку, мы могли бы реализовать этуall
функцию как:Надеюсь, это поможет.
источник
has
наisPartOf
илиisIn
илиelem
Вы также можете попробовать:
источник
lodash обеспечивает
_.isEqual()
глубокое сравнение. Это очень удобно, если вы не хотите писать свои собственные. Начиная с lodash 4,_.isEqual()
правильно сравнивает Sets.источник
Другой ответ будет работать нормально; вот еще одна альтернатива.
Однако имейте в виду, что при этом не проводится глубокое сравнение на равенство. Так
вернет false. Если два вышеуказанных набора следует считать равными, нам нужно перебрать оба набора, выполняя глубокие сравнения качества для каждого элемента. Мы оговариваем наличие
deepEqual
распорядка. Тогда логика была быЧто это делает: для каждого члена s1 найдите глубоко равный член s2. Если он найден, удалите его, чтобы его нельзя было использовать снова. Эти два набора полностью равны, если все элементы в s1 находятся в s2, а s2 исчерпан. Не проверено.
Вы можете найти это полезным: http://www.2ality.com/2015/01/es6-set-operations.html .
источник
Ни одно из этих решений не возвращает ожидаемую функциональность такой структуре данных, как набор наборов. В своем текущем состоянии набор Javascript бесполезен для этой цели, поскольку расширенный набор будет содержать повторяющиеся подмножества, которые Javascript ошибочно считает отдельными. Единственное решение, которое я могу придумать, - это преобразовать каждое подмножество в массив , отсортировать его и затем кодировать как String (например, JSON).
Решение
Основное использование
Окончательный тест: набор наборов
источник
[...set1].sort().toString() === [...set2].sort().toString()
Причина, по которой ваш подход возвращает false, заключается в том, что вы сравниваете два разных объекта (даже если они имеют одинаковый контент), поэтому сравнение двух разных объектов (не ссылок, а объектов) всегда возвращает вам ложь.
Следующий подход объединяет два набора в один и просто тупо сравнивает размер. Если то же самое, то то же самое:
Вверх : это очень просто и коротко. Нет внешней библиотеки, только vanilla JS
Обратная сторона : это, вероятно, будет медленнее, чем просто перебор значений, и вам понадобится больше места.
источник
Сравнение двух объектов с помощью ==, ===
При использовании оператора
==
или===
для сравнения двух объектов вы всегда получите результат,false
если только эти объекты не ссылаются на один и тот же объект . Например:В противном случае == приравнивается к false, даже если объект содержит те же значения:
Возможно, вам придется рассмотреть возможность ручного сравнения
В ECMAScript 6 вы можете заранее преобразовать наборы в массивы, чтобы увидеть разницу между ними:
ПРИМЕЧАНИЕ:
Array.from
это одна из стандартных функций ECMAScript 6, но она не поддерживается широко в современных браузерах. См. Таблицу совместимости здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Browser_compatibilityисточник
b
которых нетa
?b
-a
это проверить, нет лиa.size === b.size
.a.size === b.size
сначала на короткое замыкание сравнение отдельных элементов, если нет необходимости?has
операция над наборами разработана так, чтобы быть очень эффективной, в отличие отindexOf
операции над массивами. Следовательно, имеет смысл изменить функцию фильтра наreturn !b.has(i)
. Это также избавило бы от необходимости преобразовыватьb
в массив.Я создал быстрый полифилл для Set.prototype.isEqual ()
Github Gist - Set.prototype.isEqual
источник
Основываясь на принятом ответе, предполагая поддержку
Array.from
, вот однострочный:источник
eqSet = (a,b) => a.size === b.size && [...a].every(b.has.bind(b))
Если наборы содержат только примитивные типы данных или объекты внутри наборов имеют ссылочное равенство, тогда есть более простой способ
const isEqualSets = (set1, set2) => (set1.size === set2.size) && (set1.size === new Set([...set1, ...set2]).size);
источник
В тестах я придерживаюсь такого подхода:
источник
a=[1,2,3]
иb=[1,2,3,4]
, он скажет, что они такие же. Так что я думаю , вам нужен дополнительный чек , какsetA.size === setB.size
Очень небольшая модификация, основанная на ответе @Aadit M Shah:
Если у кого-то еще возникла проблема, как у меня, из-за какой-то причуды последней версии babel, пришлось добавить здесь явное условие.
(Также для множественного числа я думаю
are
, что это немного более интуитивно понятно для чтения вслух 🙃)источник
1) Проверьте, равны ли размеры. Если нет, то они не равны.
2) перебрать каждый элемент A и проверить, что существует в B. Если один из них не работает, верните
unequal
3) Если два вышеуказанных условия не выполняются, это означает, что они равны.
2) Способ 2
источник
forEach
методе НЕ приведет к возврату родительской функции.