changes.Where(p => Evaluate(p)).Subscribe(p => { // Do something });
但你怎么能做到这一点,以便在满足标准后获得标准值和n值(并且这些n值不必与评估标准相匹配)?
Evaluate(p)
上返回的流和一个后面的值(然后再开始评估p
)答案 0 :(得分:4)
请查看SkipWhile的Take和IEnumerable扩展方法。您可以尝试以下代码:
changes.SkipWhile(change => Evaluate(change) == false).Take(n).Subscribe(change => { /* do something */ });
修改强> 的
使用n
项目的尾部从序列中获取所有匹配项目的新代码(不重复检索项目)
// Let's assume elements in the sequence are of type Change
int i = 0;
Func<Change, bool> evaluateWithTail = change =>
{
if (i <= 0 || i > n)
{
i = Evaluate(change) ? 1 : 0;
}
else
{
i++;
}
return i > 0;
}
// Please note delegate is specified as parameter directly - without lambda expression
changes.Where(evaluateWithTail).Subscribe(change => { /* do something */ });
答案 1 :(得分:3)
这是另一个更短的实现:
var filtered = source
.SkipWhile( x => !Criteria(x) )
.Take(3)
.Repeat()
答案 2 :(得分:2)
我认为你不能通过组合现有的运算符来创建一个Rx运算符,因为基本上你想要的是使用Where
运算符,但是在它匹配之后你想要为下一个N“关闭它”元素。好的,显然你可以使用Repeat
运算符来证明Rx是如何组合的。
无论如何,您还可以使用创建自己的Rx运算符的最佳实践创建一个新运算符:
static class Extensions {
public static IObservable<T> WhereThenTake<T>(
this IObservable<T> source,
Predicate<T> predicate,
Int32 count
) {
if (source == null)
throw new ArgumentNullException("source");
if (predicate == null)
throw new ArgumentNullException("predicate");
if (count < 0)
throw new ArgumentException("count");
return Observable.Create<T>(
observer => {
var finished = false;
var n = 0;
var disposable = source.Subscribe(
x => {
if (!finished) {
if (n > 0) {
observer.OnNext(x);
n -= 1;
}
else if (predicate(x)) {
n = count;
observer.OnNext(x);
}
}
},
ex => { finished = true; observer.OnError(ex); },
() => { finished = true; observer.OnCompleted(); }
);
return disposable;
}
);
}
}
然后您可以像这样使用它(Evaluate
是您的谓词,n
是谓词匹配后要通过的项目数量):
changes.WhereThenTake(Evaluate, n).Subscribe( ... );