Добавление пользовательской функции сравнения для наборов (и других контейнеров) [duplicate]

Angular1

Для людей, которые используют AngularJS , может справиться с этой ситуацией, используя Promises.

Здесь it говорит,

Обещания могут использоваться для отключения асинхронных функций и позволяют объединять несколько функций вместе.

Вы можете найти приятное объяснение здесь .

Пример, найденный в docs , упомянутом ниже.

  promiseB = promiseA.then(
    function onSuccess(result) {
      return result + 1;
    }
    ,function onError(err) {
      //Handle error
    }
  );

 // promiseB will be resolved immediately after promiseA is resolved 
 // and its value will be the result of promiseA incremented by 1.

Angular2 and Later

In Angular2, посмотрите на следующий пример, но его рекомендовал использовать Observables с Angular2.

 search(term: string) {
     return this.http
  .get(`https://api.spotify.com/v1/search?q=${term}&type=artist`)
  .map((response) => response.json())
  .toPromise();

}

Вы можете использовать это таким образом,

search() {
    this.searchService.search(this.searchField.value)
      .then((result) => {
    this.result = result.artists.items;
  })
  .catch((error) => console.error(error));
}

См. здесь оригинал . Но TypScript не поддерживает native es6 Promises , если вы хотите его использовать, для этого вам может понадобиться плагин.

Кроме того, здесь представлены обещания spec определите здесь.

86
задан czerny 20 April 2015 в 22:22
поделиться

3 ответа

Объект ES6 Set не имеет методов сравнения или настраиваемой расширяемости.

Методы .has(), .add() и .delete() работают только с того, что они являются одним и тем же фактическим объектом или одинаковым значением для примитива и не имеют возможности подключать или заменять только эту логику .

Вы могли бы предположительно получить свой собственный объект из Set и заменить методы .has(), .add() и .delete() тем, что сначала провело глубокое сравнение объектов, чтобы найти, если элемент уже в наборе, но производительность, вероятно, не будет хорошей, поскольку основной объект Set не будет вообще помогать. Вам, вероятно, придется просто выполнить итерацию грубой силы по всем существующим объектам, чтобы найти совпадение, используя собственный пользовательский сопоставление, прежде чем вызывать оригинал .add().

Вот некоторая информация из этой статьи и обсуждение функций ES6:

5.2 Почему я не могу настроить, как карты и наборы сравнивают ключи и значения?

Вопрос: Было бы хорошо, если бы были способом настроить, какие ключи карты и какие установленные элементы считаются равными. Почему нет?

Ответ: эта функция отложена, так как ее трудно реализовать правильно и эффективно. Один из вариантов - передать обратные вызовы коллекциям, которые задают равенство.

Другим вариантом, доступным в Java, является указание равенства посредством метода, реализующего объект (equals () в Java). Однако этот подход является проблематичным для изменяемых объектов: в общем случае, если объект изменяется, его «местоположение» внутри коллекции также должно измениться. Но это не то, что происходит на Java. Вероятно, JavaScript будет более безопасным путем только для сравнения по значению для специальных неизменяемых объектов (так называемых объектов ценности). Сравнение по значению означает, что два значения считаются равными, если их содержимое равно. Примитивные значения сравниваются по значению в JavaScript.

58
ответ дан jfriend00 26 August 2018 в 04:13
поделиться

Чтобы добавить к ответам здесь, я пошел дальше и реализовал оболочку Map, которая принимает пользовательскую хеш-функцию, пользовательскую функцию равенства и сохраняет различные значения, которые имеют эквивалентные (пользовательские) хэши в кодах.

Как и ожидалось, он оказался медленнее , чем метод конкатенации строки czerny .

Полный источник здесь: https://github.com / makoConstruct / ValueMap

17
ответ дан Community 26 August 2018 в 04:13
поделиться

Возможно, вы можете попытаться использовать 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);

2
ответ дан GuaHsu 26 August 2018 в 04:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: