Могу ли я использовать ownUntilKeyChanged для удаления повторяющихся объектов?

Я новичок в rxjs в Angular 7, у меня есть api, который возвращает данные пользователя. Я хочу удалить объекты с одинаковыми именами, я почти не пробовал его с помощью отличногоUntilKeyChanged (), но вывод в консоли такой же, как и из api отклик. а также могу я напрямую использовать возвращенные данные из службы, поскольку ответ уже является наблюдаемым с использованием интерфейса без использования From () или 0f () в компоненте.

Это для angular 7 и Rxjs 6, я использую angular в течение одного года, но я до сих пор не использовал Rxjs, у меня много путаницы в Rxjs, могу ли я использовать ответ Http от службы непосредственно в компоненте, или я хочу Чтобы использовать любые операторы для преобразования ответа в виде потока вкратце, могу ли я использовать Json response непосредственно в компоненте для использования различных операторов, таких как find (), first (), ignoreElements и т. д.

user.service.ts

  private urlLara = 'http://laravel.technalatus.com/public/api/'
  public getusers(): Observable<User> {
    const head = new HttpHeaders({
      'Accept': 'application/json',
      'Content-Type': 'application/json',
    })
    return this.http.get<User>(this.urlLara + 'users', { headers: head 
    });
  }

component.ts

export class AppComponent implements OnInit {
  title = 'angularrxjs';
  items: {};
  post: Post;
  user: User;
  public searchTerm: string;

  constructor(private UserService: UserService) {

  }

  ngOnInit() {
    this.distinct()
  }

  public Duchanged() {
    // custom compare for name
    this.UserService.getusers().pipe(distinctUntilChanged((prev, curr) => prev.name === curr.name))
      .subscribe(console.log);

  }

Получение вывода как

[
{id: 2, name: "alshoja", email: "[email protected]", email_verified_at: null, type: "admin"},
{id: 3, name: "Ellaware", email: "[email protected]", email_verified_at: null, type: "user"},
{id: 17, name: "alshoja", email: "[email protected]", email_verified_at: null, type: "user"}
]

Ожидая выхода как

[
{id: 2, name: "alshoja", email: "[email protected]", email_verified_at: null, type: "admin"},
{id: 3, name: "Ellaware", email: "[email protected]", email_verified_at: null, type: "user"},
]

person Educ Dev Team    schedule 07.08.2019    source источник


Ответы (2)


Ваше представление о том, как работают distinctUntilKeyChanged и distinctUntilChanged, неверно. Согласно документации

  • distinctUntilKeyChanged излучает только тогда, когда указанное значение ключа изменилось. (Источник: docs)
  • distinctUntilChanged излучает только тогда, когда текущее значение отличается от последнего. (Источник: документы)

Поскольку в каждом объекте name отличается от последнего объекта, он будет излучать каждый раз. В вашем случае distinctUntilKeyChanged или distinctUntilChanged будут работать только в том случае, если ваши "отдельные" элементы расположены в таком порядке, как показано ниже.

[
  { id: 3, name: "Ellaware", email: "[email protected]", email_verified_at: null, type: "user" },
  { id: 2, name: "alshoja", email: "[email protected]", email_verified_at: null, type: "admin" },
  { id: 17, name: "alshoja", email: "[email protected]", email_verified_at: null, type: "user" }
]

Вместо этого вы можете использовать distinct

import { distinct, toArray } from 'rxjs/operators';

public Duchanged() {
  this.UserService.getusers()
  .pipe(
    distinct(user => user.name),
    toArray()
  )
  .subscribe(console.log);
}
person nash11    schedule 07.08.2019
comment
Вы понимаете, что ваш ответ неполный? Результатом отдельной трубы являются отдельные объекты. Не массив. - person Carsten; 07.08.2019
comment
Я понял вашу точку зрения @ nash11, могу ли я напрямую использовать возвращенный ответ в компоненте в том виде, в котором он поступил из службы? если может помочь, это будет плохо - person Educ Dev Team; 07.08.2019
comment
@Carsten - Плохо, он упомянул в своем вопросе, что получает массив в качестве вывода, поэтому я предположил, что это делает. Я обновил свой ответ - person nash11; 07.08.2019
comment
@EducDevTeam - ознакомьтесь с обновленным ответом, чтобы узнать, как получить результат в виде массива. - person nash11; 07.08.2019
comment
@ nash11, получил ответ в виде массива, но массив содержит повторяющееся имя, может быть мой плохой - person Educ Dev Team; 07.08.2019
comment
@EducDevTeam, это правильный ответ. Минимальные результаты тестов в том, что вы хотите. (from (this.test) .pipe (independent (a = ›a.name), toArray ()). subscribe (console.log);) (this.test - ваш массив). - person Carsten; 07.08.2019
comment
@Carsten, я хочу избежать дублирования в результате, но получаю тот же результат, что и от Api, извините, мой вопрос об удалении объектов с одинаковыми именами - person Educ Dev Team; 07.08.2019
comment
@EducDevTeam Значит, вы что-то не так делаете .. Ответ правильный. - person Carsten; 07.08.2019

Оператор distinctUntilChanged будет игнорировать новые результаты из потока, которые точно такие же, здесь у вас есть поток только с одним результатом, который является массивом пользователей.

Что вам следует сделать, так это использовать оператор map и использовать массивы filter для удаления дубликатов из вашего массива.

this.UserService.getusers().pipe(
   map((users) => users.filter((v,i) => users.indexOf(v) === i))
   .subscribe(console.log);
person Eliran Eliassy    schedule 07.08.2019