为什么没有 RxJS 运算符来从流中删除特定项目?

Why is there no RxJS operator to remove specific items from a stream?

我在尝试从可观察流中删除 属性 时遇到了难以置信的困难。我有一个 Observable,它在 url(angular 的 ActivatedRoute.queryParams)中发出查询参数对象。我正在尝试从发出的值中删除键和值并调用 distinctUntilChanged() 以便它们的更改不会触发我的观察者。

pluck() 允许您只允许流中的一个参数通过,filter() 允许您过滤整个流,skip() 运算符允许您跳过整个流发射,throttle() 来限制排放量。尽管做与 pluck() 相反的事情——你希望允许流中除一个值以外的所有值都通过——并不存在。最接近完成它的是一个 map(),它创建一个新对象,删除 属性,然后 returns 那个新对象,但这充其量只是小故障,而且通常是行不通的。

除了我试图忽略的参数属性之外,我已经求助于为所有查询参数属性创建单独的订阅。我想必须有更好的方法来解决这个问题,是否有一些我缺少或解决的神奇运算符?当 pluck() 之类的东西存在时,为什么反应库中缺少如此明显的运算符?

编辑:

代码:

this.activatedRoute.queryParams
  .map((value) => {
    const newObj = Object.assign({}, value);
    delete newObj['page'];
    return newObj;
  })
  .distinctUntilChanged()
  .skip(1)
  .subscribe(
    (value) => console.log(value)
  );

您的代码不起作用的原因似乎是具有相同属性和值的对象在 JavaScript 中不被视为相等,因此 distinctUntilChanged 不起作用,因为
{prop: "value"} === {prop: "value"}false.

有一个简单的解决方案。不推荐用于长列表等,因为它在负载下表现不佳,但如果只是路由更改,那不会很快更改很多次。

this.activatedRoute.queryParams
  .map((value) => {
    // Your existing code or
    const {page, ...otherProps} = value;
    return otherProps;
  })
  // You tell it what to use as comparison
  .distinctUntilChanged((oldProps, newProps) => 
    JSON.stringify(oldProps) === JSON.stringify(newProps)
  )
  // Not sure you still need this
  .skip(1)
  .subscribe(
    (value) => console.log(value)
  );

您可以在 Object comparison in JavaScript 中阅读更多比较对象的方法。

更新:

这个答案被否决了,因为据说 JSON.stringify() 有时会以不同的顺序提供属性。

JSON.stringify() 的细节并不是真正答案的核心,这就是为什么我链接到另一个专注于对象比较的 SO 答案,但是,简单的谷歌搜索显示了另一个你可以使用的答案: sort object properties and JSON.stringify

为了跟随答案,您更改此位:

  .distinctUntilChanged((oldProps, newProps) => 
    JSON.stringify(oldProps) === JSON.stringify(newProps)
  )

变成类似这样的东西:

  .distinctUntilChanged((oldProps, newProps) => {
    // You can put this at the beginning of the file
    // It doesn't need to live inside the RxJS operator
    const createComparisonString = 
        (obj) => JSON.stringify(obj, Object.keys(obj).sort());

    return createComparisonString(oldProps) === createComparisonString(newProps);
  })

但是,JSON.stringify 并不是比较对象的唯一方法。如果您愿意,请参阅上面引用的答案以获取其他选项的示例。再次 Object comparison in JavaScript.