如何从 Observable 中过滤数组以获得浅拷贝而不是深拷贝?

How to filter an array from an Observable to get shallow copies instead of deep ones?

我的组件使用一些数据("ksr" 项目的数组,其中有一个 code 属性 可以被认为是一个 id)通过 xhr 加载到 Observable

dictionaries = {
  ksr$: this.dictionaryService.fetchDictionaryByName('KSR'),
  ...
}

并且其中的一部分被过滤到另一个 Observable 中,如下所示:

formSuggestions = {
  ksrCodes$: this.dictionaries.ksr$.pipe(map((plainKsrArray: Array<any>) =>
    plainKsrArray.filter(ksrItem => ksrItem.levelName == "position"
  )),
  ...
}

我预计在加载数据后,.formSuggestions 中的项目是 .dictionaries 中项目的浅表副本,但情况似乎并非如此。具体如下测试函数

async debugDictionariesAndSuggestions() {
  let dictionary = await this.dictionaries.ksr$.toPromise();
  let dItem = dictionary.find(item => item.code == '01.11.11.01.1.01.01-0001');
  let suggestions = await this.formSuggestions.ksrCodes$.toPromise();
  let sItem = suggestions.find(item => item.code == '01.11.11.01.1.01.01-0001');
  console.log('found by code:', dItem, sItem, dItem == sItem ? 'same' : 'not same');
  console.log(JSON.stringify(dItem) == JSON.stringify(sItem) ? 'they look the same' : 'they look different');
}

dictionarysuggestions 中找到项目,但报告它们不是同一事物(尽管 dItemsItem 的所有嵌套属性都是同样,报告 "they look the same")。为什么会这样,我如何修改来自可观察对象的此类数据的处理方式(如何将 dictionaries.ksr$ 过滤为 formSuggestions.ksrCodes$),以便后者包含前者的项目(浅拷贝)?

就像@JBNizet 指出的那样,shareReplay 运算符是解决该问题的一种非常简单的方法。从 http 服务 observable 派生的 observable 的正常行为是 - 每个订阅(在我的例子中是承诺的:await this.dictionaries.ksr$.toPromise()await this.formSuggestions.ksrCodes$.toPromise())触发一个新请求。但是如果我这样修改它:

dictionaries = {
  ksr$: this.dictionaryService.fetchDictionaryByName('KSR').pipe(shareReplay()),
  ...
}

dictionaries.ksr$ 可观察的和派生的只触发一个请求,结果值是共享的,这正是我一直在寻找的。