我有一组IObservable<bool>
s - 让他们称呼sources
- 如果所有输入都为真,我想要和这些值的AND产生true
:
sources.CombineLatest().Select(values => values.All(x => x))
但是,如果其中一个来源在false
的值完成时完成(这意味着所有来源永远不会再为true
),我想发信号false
并完成
我该怎么做?
答案 0 :(得分:4)
这是我对它的看法,没有发布和调度程序的需要:
public static IObservable<bool> Foo(
this IEnumerable<IObservable<bool>> sources)
{
var projectedSources = sources.Select(source => source
.Materialize()
.Scan(
new
{
Latest = true,
IsCompleted = false
},
(tuple, notification) => new
{
Latest = notification.HasValue ? notification.Value : tuple.Latest,
IsCompleted = tuple.IsCompleted || !notification.HasValue
}));
return projectedSources
.CombineLatest()
.TakeWhile(list => list.All(x => !x.IsCompleted || x.Latest))
.Select(list => list.All(x => x.Latest))
.DistinctUntilChanged();
}
首先,我们实现每个源并扫描它,记录它的最后一个值以及源是否已经完成。然后,我们组合这些来源,只有在所有来源未完成或具有最新值true
的情况下才从结果中获取。然后,我们将所有源的值投影到单个输出值。
注意:您可能希望使用值true
启动源代码(如上面的解决方案中所述)。试验它。
答案 1 :(得分:2)
我认为这样做:
public static IObservable<bool> Foo(
this IEnumerable<IObservable<bool>> sources)
{
var sourceArray = sources.Select(s => s.Publish().RefCount()).ToArray();
var terminator = sourceArray
.ToObservable(Scheduler.Default)
.SelectMany(x => x.StartWith(true).LastAsync().Where(y => y == false));
var result = sourceArray
.CombineLatest(values => values.All(x => x))
.DistinctUntilChanged()
.TakeUntil(terminator);
return result;
}
有一些发布可以防止副作用,但是密钥是terminator
,它会监视最后一个值为false的流。