4 ответа:
в ЕС6
Set
объект не имеет методов сравнения или пользовательской расширяемости сравнения.The
.has()
,.add()
и.delete()
методы работают только с тем, что это один и тот же фактический объект или одно и то же значение для примитива и не имеют средств для подключения или замены только этой логики.вы могли бы предположительно получить свой собственный объект из
Set
и заменить.has()
,.add()
и.delete()
методы с чем-то, что сделал детальное сравнение объекта с найдите, если элемент уже находится в наборе, но производительность, скорее всего, не будет хорошей, так как базовый
как говорится в ответ jfriend00 настройка отношения равенства, вероятно,не возможно.
следующий код представляет собой схему вычислительно эффективной (но памяти дорого) решение:
class GeneralSet { constructor() { this.map = new Map(); this[Symbol.iterator] = this.values; } add(item) { this.map.set(item.toIdString(), item); } values() { return this.map.values(); } // ... }
каждый вставленный элемент должен реализовать
toIdString()
метод, который возвращает строку. Два объекта считаются равными тогда и только тогда, когда ихtoIdString
методы возвращает то же значение.
чтобы добавить к ответам здесь, я пошел вперед и реализовал оболочку карты, которая принимает пользовательскую хэш-функцию, пользовательскую функцию равенства и хранит различные значения, которые имеют эквивалентные (пользовательские) хэши в ведрах.
предсказуемо, это оказалось медленнее чем метод конкатенации строк черни.
полный источник здесь:https://github.com/makoConstruct/ValueMap
может быть, вы можете попробовать использовать
JSON.stringify()
для глубокого сравнения объектов.например :
const arr = [ {name:'a', value:10}, {name:'a', value:20}, {name:'a', value:20}, {name:'b', value:30}, {name:'b', value:40}, {name:'b', value:40} ]; const names = new Set(); const result = arr.filter(item => !names.has(JSON.stringify(item)) ? names.add(JSON.stringify(item)) : false); console.log(result);