对IObservable进行分组并筛选出计数大于1的IObservable

时间:2014-03-25 16:21:56

标签: system.reactive

我有这段代码:

IObservable<Provider> allProviders = _context.ReadAllProviders();

Provider[] results = allProviders
    .ToEnumerable()
    .GroupBy(
        p => p.Name,
        (name, group) =>
        {
            var array = group.ToArray();
            return array.Length == 1 ? array[0] : null;
        },
        StringComparer.OrdinalIgnoreCase)
    .Where(p => p != null)
    .ToArray();

我正在过滤掉在Name属性上不唯一的提供商,但我想在GroupBy而不是IObservable上执行IEnumerable。打算在事后做更多可观察的事情。在过滤分组的observable时,我遇到了语法问题:

IObservable<Provider> allProviders = _context.ReadAllProviders();

IObservable<Provider> results = allProviders
    .GroupBy(p => p.Name, StringComparer.OrdinalIgnoreCase)
    .Where(group =>
    {
        IObservable<int> count = group.Count();

        return count == 1; // this doesn't compile obviously. I'm not sure where to go from here.
    })
    .Merge();

2 个答案:

答案 0 :(得分:1)

逻辑上,在源流完成之前,您无法知道Observable组中将有多少成员 - 因为任何元素都可能对任何组有贡献。

因此,在源流完成之前,您无法按计数过滤组,并且必须同意缓存结果然后处理它们。

换句话说,IEnumerable<T>是前往这里的方式。当然,你可以把它变回IObservable<T>,但可能没有意义。

顺便说一句,如果您确实需要过滤组,请在Select子句中进行,如此简单示例中所示。但是,由于上述原因,它不适用于Count()

var source = Observable.Range(0, 10);
source.GroupBy(n => n < 5)        
      .Select(x => x.Where(y => y % 2 == 0));

答案 1 :(得分:0)

我认为这可以产生一个独特的名为Provider对象的流。

IObservable<Provider> results = allProviders
    .GroupBy(p => p.Name)
    .SelectMany(xs => xs
        .Skip(1)
        .Take(1)
        .Zip(xs, (x1, x0) => x0))
    .Where(p => p != null);