我可以使用 distinctUntilKeyChanged 删除重复的对象吗?

Posted

技术标签:

【中文标题】我可以使用 distinctUntilKeyChanged 删除重复的对象吗?【英文标题】:Can i use distinctUntilKeyChanged for removing duplicate objects? 【发布时间】:2019-12-14 16:11:43 【问题描述】:

我是 Angular 7 中 rxjs 的新手,我有一个返回用户详细信息的 api。我想删除具有相同名称的对象,我几乎没有尝试使用 distinctUntilKeyChanged() 但在控制台中获得的输出与来自 api 响应。我也可以直接使用从服务返回的数据,因为响应已经是使用接口的 Observable,而无需在组件中使用 From() 或 0f()。

这是针对 angular 7 和 Rxjs 6 的,我已经使用 angular 一年了,但直到现在我还没有使用 Rxjs,我在 Rxjs 中遇到了很多困惑,我可以直接在组件中使用来自服务的 Http 响应,否则我是否想使用任何运算符将响应转换为简短的流我可以直接在组件中使用 Json 响应来使用不同的运算符,如 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 
    );
  

组件.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: "alshoja@gmail.com", email_verified_at: null, type: "admin",
id: 3, name: "Ellaware", email: "abhi@gmail.com", email_verified_at: null, type: "user",
id: 17, name: "alshoja", email: "c@g.com", email_verified_at: null, type: "user"
]

期望输出为

[
id: 2, name: "alshoja", email: "alshoja@gmail.com", email_verified_at: null, type: "admin",
id: 3, name: "Ellaware", email: "abhi@gmail.com", email_verified_at: null, type: "user",
]

【问题讨论】:

【参考方案1】:

您对distinctUntilKeyChangeddistinctUntilChanged 工作原理的看法不正确。根据文档

distinctUntilKeyChanged 仅在指定键值更改时发出。 (来源:docs) distinctUntilChanged 仅在当前值与上一个不同时发出。 (来源:docs)

由于在每个对象中name 都从最后一个对象更改,因此每次都会发出。在您的情况下,distinctUntilKeyChangeddistinctUntilChanged 仅在您的“不同”项目按如下顺序排列时才有效

[
   id: 3, name: "Ellaware", email: "abhi@gmail.com", email_verified_at: null, type: "user" ,
   id: 2, name: "alshoja", email: "alshoja@gmail.com", email_verified_at: null, type: "admin" ,
   id: 17, name: "alshoja", email: "c@g.com", 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);

【讨论】:

您是否意识到您的答案不完整?不同管道的结果是单个对象。不是数组。 我明白你的意思@nash11,我可以直接使用组件中返回的响应,因为它来自服务吗?如果能帮上忙,那就太好了 @Carsten - 我的错,他在他的问题中提到他正在获取一个数组作为他的输出,所以我假设正在这样做。我已经更新了我的答案 @EducDevTeam - 查看更新后的答案,了解如何将输出作为数组获取。 @nash11,得到了数组的答案,但数组包含重复的名称,可能是我的错【参考方案2】:

distinctUntilChanged 运算符将忽略流中完全相同的新结果,这里你有一个只有一个结果的流,即用户数组。

您应该做的是使用map 运算符并使用数组filter 从数组中删除重复项。

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

【讨论】:

【参考方案3】:
distinctUntilChanged -> It will check only current and prev object.Before passing the JSON ,You should sort based on name then use distinctUntilChanged();
the result of this.UserService.getusers() should be like this:
[
id: 2, name: "alshoja", email: "alshoja@gmail.com", email_verified_at: null, type: "admin",
id: 17, name: "alshoja", email: "c@g.com", email_verified_at: null, type: "user",
id: 3, name: "Ellaware", email: "abhi@gmail.com", email_verified_at: null, type: "user"

【讨论】:

以上是关于我可以使用 distinctUntilKeyChanged 删除重复的对象吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 ScriptEditor、SharePoint 中使用 Json 吗?

我可以使用啥图表来显示 Html 事件和操作

HTML5 本地存储 - 我可以为每个键存储多个值,如果不能,我可以使用啥替代方案?

我可以从 WPF 窗口获取 HDC 以便我可以使用 Gdi+ API 绘制它吗?

我可以使用 Rails 制作 phongap 应用吗

我可以使用啥库在 C# 中处理 VoIP 流?