2013-02-25 14 views
5

Diyelim ki, 1, 2, 3, 4, 5 sitelerinin içeriğini almak için web'e bir sekans çıkıyor (ancak öngörülemeyen sırayla geri dönecek). İkinci sıra, aynı kayıtlar 1, 2, 3, 4, 5 ile ilgili bağlamı almak için bir veri tabanına gidecektir (ancak bu örneğin amaçları için öngörülemeyen sırayla geri dönecektir).İki Diziyi Eşleşen Bir Anahtarla Birlikte Eşleyebilir miyim?

Her eşleşen çift her iki dizide de hazır olduğunda bunları bir sırayla bir araya getirecek bir Rx uzantısı yöntemi var mı? Yani, eğer birinci dizi 4,2,3,5,1 sırasıyla geri dönerse ve ikinci dizi 1,4,3,2,5 mertebesinde geri dönerse, birleştirilmiş sekans (4,4), (3) olacaktır. , 3), (2,2), (1,1), (5,5) - her bir çift hazır olduğunda. Birleştir ve Zip'e baktım ama tam olarak aradığım şey gibi görünmüyorlar.

Eşleşmeyen çiftleri atmak istemem, basit bir .Where.Select kombinasyonunu göz önünde bulundurmayı düşünüyorum.

cevap

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

Aşağıdaki test, doğru sonuçları verir. Anahtarları ve değerleri kullanarak veri kullanıyorsanız, şu anda sadece ints şu anda almak, i.Key yerine i.

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); 

verimleri: Brandon cevaben

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

Düzenleme: öğelerin farklı sınıfları (Aclass ve BClass) olan durum için

aşağıdaki ayarlama yapılabilir.

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)); 
+0

Vay, harika! Çok teşekkür ederim, burada ihtiyacım olanı birleştirme ile elde edebileceğimi fark etmemiştim. Sonuncu dizilimin sonunda çiftler vermesini bekledim: .Select (g => new {First = g.ElementAt (0), Second = g.ElementAt (1)}) – blaster

+0

Bu sadece eğer 2 gözlemlenebilir sekans aynı Tipdedir. Sözü edilen 1 akış "bağlam" ve diğeri ise farklı türdeki veriyi ifade eden "içerik" idi. – Brandon

+0

@Brandon, bu durum için bir düzenleme ekledim. –

1

Birlikte eşleştirmek istediğiniz 2 gözlemlenebilir diziniz var mı? GroupBy ile birlikte Rxx çiftinden

çifti yardımcı olabilir. Ben aşağıdakine benzer bir kod

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 }; 
     }); 

`` `

bunu test edilmemiş ve hata işleme için bir şey ilave ettik istediğini yapabilir düşünüyorum, ama bu istediğini düşünüyorum .

İlgili konular