"分发"其他序列中的序列

时间:2017-01-12 12:16:19

标签: sequence system.reactive

我有一个IObservable,可以生成如下序列:

A1, A2, A3, A4, B1, B2, B3, B4, C1, C2, C3, C4, D1, D2, D3, D4, ...

我想要一个方法:

IObservable<T>[] Distribute(IObservable<T>, count)

当在IObservable上调用时,会生成其他IObservable - 在这种情况下为4 - 这样每个IObservable的输出将是来自相对位置的元素&#34;在原始序列中(伪代码):

GetOutput(unzipped[0]) = { A1, B1, C1, D1, ... };
GetOutput(unzipped[1]) = { A2, B2, C2, D2, ... };

这与向N人发牌(N = count)的人相同,当你按顺序为每个人提供一张牌时,然后重新开始。

问题是:

  1. 是否可以使用现有的Rx方法获得该功能?
  2. 如果没有,我怎么能自己实施呢?我觉得在索引中使用Where模数除法是可以接受的,除非上面问题1的答案是&#34;是&#34; ...

1 个答案:

答案 0 :(得分:4)

在Rx中,您通常会尽可能长时间留在IObservable土地。所以更自然的签名是IObservable<IObservable<T>> Distribute(IObservabe<T> source, int count),看起来像这样:

public static IObservable<IObservable<T>> Distribute<T>(this IObservable<T> source, int count)
{
    var toReturn = source.Select((t, i) => Tuple.Create(t, i))
        .GroupBy(t => t.Item2 % count)
        .Select(g => g.Select(t => t.Item1))
    return toReturn;
}

你可以像这样的数组得到它:

public static IObservable<T>[] DistributeArray<T>(this IObservable<T> source, int count)
{
    var toReturn = new IObservable<T>[count];
    for (int i = 0; i < count; i++)
    {
        var enclosedI = i;
        toReturn[enclosedI] = source
            .Where((t, j) => j % count == enclosedI);
    }
    return toReturn;
}