5

シーケンス 1 が Web に出て、サイト 1、2、3、4、5 のコンテンツを取得するとします (ただし、返される順序は予測できません)。

シーケンス 2 は、データベースにアクセスして、これらの同じレコード 1、2、3、4、5 に関するコンテキストを取得します (ただし、この例では、予測できない順序で返されます)。

一致する各ペアが両方のシーケンスで準備ができているときに、これらを 1 つのシーケンスに結合する Rx 拡張メソッドはありますか? つまり、最初のシーケンスが 4,2,3,5,1 の順序で返され、2 番目のシーケンスが 1,4,3,2,5 の順序で返される場合、マージされたシーケンスは (4,4), (3 ,3)、(2,2)、(1,1)、(5,5) - 各ペアの準備ができ次第。Merge と Zip を見てきましたが、探しているものとはまったく違うようです。

単純な .Where.Select の組み合わせを除外すると思うので、一致しないペアを破棄したくありません。

4

2 に答える 2

3
var paired = Observable
    .Merge(aSource, bSource)
    .GroupBy(i => i)
    .SelectMany(g => g.Buffer(2).Take(1));

以下のテストでは、正しい結果が得られます。キーと値を持つデータを使用している場合は、i.Key の代わりに i.Key でグループ化する必要があります。

var aSource = new Subject<int>();
var bSource = new Subject<int>();

paired.Subscribe(g => Console.WriteLine("{0}:{1}", g.ElementAt(0), g.ElementAt(1)));

aSource.OnNext(4);
bSource.OnNext(1);
aSource.OnNext(2);
bSource.OnNext(4);
aSource.OnNext(3);
bSource.OnNext(3);
aSource.OnNext(5);
bSource.OnNext(2);
aSource.OnNext(1);
bSource.OnNext(5);

収量:

4:4
3:3
2:2
1:1
5:5

Brandon に応じて編集します。

アイテムが異なるクラス (AClass と BClass) である状況では、次の調整を行うことができます。

using Pair = Tuple<AClass, BClass>;

var paired = Observable
    .Merge(aSource.Select(a => new Pair(a, null)), bSource.Select(b => new Pair(null, b)))
    .GroupBy(p => p.Item1 != null ? p.Item1.Key : p.Item2.Key)
    .SelectMany(g => g.Buffer(2).Take(1))
    .Select(g => new Pair(
      g.ElementAt(0).Item1 ?? g.ElementAt(1).Item1, 
      g.ElementAt(0).Item2 ?? g.ElementAt(1).Item2));
于 2013-02-25T23:41:22.800 に答える
1

では、ペアリングしたい2つの観測可能なシーケンスがありますか?

GroupByと一緒にRxxからペアリングすることがここで役立ちます。次のようなコードはあなたが望むことをするかもしれないと思います

var pairs = stream1.Pair(stream2)
       .GroupBy(pair => pair.Switch(source1 => source1.Key, source2 => source2.Key))
       .SelectMany(group => group.Take(2).ToArray()) // each group will have at most 2 results (1 left and 1 right)
       .Select(pair =>
       {
           T1 result1 = default(T1);
           T2 result2 = default(T2);

           foreach (var r in pair)
           {
              if (r.IsLeft) result1 = r.Left;
              else result2 = r.Right;
           }

           return new { result1, result2 };
       });

`` `

私はそれをテストしておらず、エラー処理のために何も追加していませんが、これはあなたが望むものだと思います。

于 2013-02-25T18:21:05.193 に答える