Как настроить равенство объектов для набора JavaScript


новый ES 6 (гармония) вводит новый Set

4 93

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