Reactive Extensions有扩展方法:
Join(this IObservable<TLeft> left, IObservable<TRight> right,
Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector,
Func<TRight, IObservable<TRightDuration>> rightDurationSelector,
Func<TLeft, TRight, TResult> resultSelector)
但是,没有重载也需要Func<TLeft, TRight, bool>
作为连接条件。结果,此方法返回左右的完整笛卡尔积。
我已将其实现为
public static IObservable<TResult> Join<TLeft, TRight, TResult>(
this IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, TRight, bool> joinCondition,
Func<TLeft, TRight, TResult> resultSelector)
{
return left.Join(right, l => Observable.Never<TLeft>(), r => Observable.Never<TRight>(),
(l, r) => new Tuple<TLeft, TRight>(l, r))
.Where(CurryTuple(joinCondition))
.Select(CurryTuple(resultSelector));
}
private static Func<Tuple<TLeft, TRight>, TResult> CurryTuple<TLeft, TRight, TResult>(Func<TLeft, TRight, TResult> func)
{
return tuple => func(tuple.Item1, tuple.Item2);
}
当我更多地使用它时,我想知道我是否可能需要更多类似的方法(可能是外连接 - 无论对于Observables意味着什么)。而不是试图实现它们(并带来潜在的错误和次优代码),我想知道是否有其他人遇到了同样的问题,是否有已经编写过的库。
有什么想法吗?
答案 0 :(得分:0)
我认为你误解了反应联合的运作方式。连接条件是事件重合,而不是您提供的二进制操作。基本上每个事件都会附加一个持续时间,同时存在来自同时存在的左右源的事件。 Have a look at this video了解更多信息。
如果持续时间不是终止的,则反应性连接的结果是笛卡尔积 - 正如您在样本中制作的那样。你正在做的是会给出一些非常差的性能特征。
您能提供大理石图表,单元测试和/或您想要实现的示例场景吗?
我怀疑没有使用Join会有更好的方法。