如何使用可观察对象执行递归搜索,而不必检查重复项?

时间:2018-12-13 14:59:15

标签: rxjs

我将在rxjs中说明问题,但我想对于任何Rx或可观察的库来说,它都是相似的。

说我有一个可观察的用户,还有一个函数getAssociates(user)返回了另一个可观察的用户。我想在可观察对象中的每个用户上使用getAssociates函数,并返回这些关联对象的可观察对象。 flatMap就足够了。

但是我还想在返回的每个关联上运行getAssociates,但不要在任何给定用户上运行两次(因为两个用户可能共享一个关联,并且如果A具有B作为关联,则B也有A作为合伙人。

我正在寻找类似于expand运算符的东西:

seedUsers.pipe( expand(user => getAssociates(user)), );

但是我该如何避免在任何给定用户上不运行两次?我可以维护可见用户的列表,但是我想以一种功能性的方式来实现它。

1 个答案:

答案 0 :(得分:0)

从概念上讲,您需要:

  • 例如使用Set
  • 跟踪已知用户
  • 在发出请求之前过滤已知用户,例如使用filter运算符

这是一个建议:

let knownIds = new Set();

getAllItems(Ids){
   return from(Ids).pipe(
     filter(id => ! knownIds.has(id)),
     concatMap(id => getAllItems(id)),
     map( id => knownIds.add(id))
   )
}

getAllItems([originalId]).subscribe( allItems=> console.log)

注意:

  • 我想您可以使用rxjs做到这一点,但是我想到的所有解决方案都不比使用set +过滤器更简单。

  • 我使用concatMap来确保您不会两次运行请求。使用mergeMap (flatMap),您可能会遇到这样的情况:

--------- Req(user1)---------------------------- resp(user1)- -----------------------

---请求(用户2)------请求(用户2)-请求(用户1)-----------------请求(用户1)-

但是,如果您最终接受每个用户两个以上的请求,则可以使用flatMap来提高速度。