【问题标题】:Filter Operator predicate function returns all items in the array过滤运算符谓词函数返回数组中的所有项目
【发布时间】:2018-11-06 00:31:33
【问题描述】:

我有一个对象数组的 Observable。每个对象都有一个“id”属性。我使用 filter 方法的目的是只返回与特定 id 匹配的对象的 observable。

当我实现以下代码时,谓词函数返回整个数组。我的期望是只有一项通过。

    this.blog$ = this.store.select('posts', 'blogs').pipe(
      filter((post, index) => {
        console.log(post[index].id == this.id);
        return post[index].id == this.id
      }),
    ).subscribe(x=>console.log(x))

第一个控制台日志在过滤器函数中,第二个从订阅方法调用。

如果我的比较器函数评估为真,仅针对某个 id,我怎样才能正确地只产生传递的对象?

【问题讨论】:

  • rxjs filter 函数用于过滤每个emit,因此如果它与数组一起发出一次,您将需要使用数组filter 函数和map 来代替
  • 好的,这让我在某个地方。在过滤器运算符中执行 posts.filter(post => post.id = this.id) 时,我现在确实看到了每个项目。但是地图功能应用在哪里呢?你能提供这个作为答案吗?
  • 你指的是数组映射方法吗?
  • 不,到 RXJS 映射函数 learnrxjs.io/operators/transformation/map.html。我在下面添加了一个答案,希望对您有所帮助

标签: angular filter rxjs observable ngrx


【解决方案1】:

rxjs 过滤器函数用于过滤每个发射,所以如果它用一个数组发射一次,你将需要使用数组过滤器函数和map 来代替

this.blog$ = this.store.select('posts', 'blogs').pipe(
  map((posts) => posts.filter((post) => post.id == this.id))
).subscribe(x=>console.log(x))

或者,如果您只需要第一个匹配项,并且希望将结果作为对象而不是具有 1 个元素的数组,则只需使用 find 数组函数即可:

this.blog$ = this.store.select('posts', 'blogs').pipe(
  map((posts) => posts.find((post) => post.id == this.id))
).subscribe(x=>console.log(x))

【讨论】:

  • 谢谢,这让 array.filter 和 rxjs 操作符 'filter' 之间的区别非常清楚了。
  • 如答案中所述,如果您希望获取项目而不是数组,则可以使用find。它也应该更有效,因为它会在找到匹配项时立即中断循环
【解决方案2】:

完整的 rx 替代方案是:

this.blog$ = this.store.select('posts', 'blogs').pipe(
  mergeAll(),
  filter(post => post.id == this.id)
).subscribe(post => console.log(post))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多