2016-08-04 7 views
1

次の実装をより宣言的な方法でクリーンアップしたいと思います。うまくいけばRx演算子がありません。Rxで配列要素をグループ化する

私は、このような何かストリームに公開されたデータの配列を持っている:

var data = new[] { 'A', 'A', 'C', 'A', 'A', 'A', 'A', 'B', 'C', 'C' }; 

を私は変更するまで、配列にデータのグループ項目にしたいので、あなたは結果は次のようになります。

var result = new[] { { 'A', 'A' }, {'C' }, { 'A', 'A', 'A', 'A' }, { 'B' }, { 'C', 'C' } }; 

私は以下を持っています。私は '選択'実装をクリーンアップしたいと思います。 Rx演算子(GroupByUntilなど)を使用するのが理想的です。

これをどのように改善できますか?

Observable.Return(data) 
      .Select(items => 
      { 
       var groupedItems = new List<List<char>>(); 

       var currentItems = new List<char>(); 
       var previousItem = items.FirstOrDefault(); 
       foreach (var currentItem in items) 
       { 
        if (previousItem != currentItem) 
        { 
         groupedItems.Add(currentItems); 
         currentItems = new List<char>(); 
        } 

        currentItems.Add(currentItem); 
        previousItem = currentItem; 
       } 
       groupedItems.Add(currentItems); 
       return (IEnumerable<IEnumerable<char>>)groupedItems; 
      }) 
      .Subscribe(groupedItems => 
      { 
       foreach (var groupedItem in groupedItems) 
       { 
        Console.WriteLine("{0} - {1}", groupedItem.First(), groupedItem.Count()); 
       } 
      }); 

答えて

3

入力ストリームが.ToObservableの文字ストリームに変換されるとき。次の実装が可能です:

var data = new[] { 'A', 'A', 'C', 'A', 'A', 'A', 'A', 'B', 'C', 'C' }; 

    var publishedData = data 
     .ToObservable() 
     .Publish() 
     .RefCount(); 

    publishedData 
     .GroupByUntil(e => e, e => e, g => publishedData.Where(i => i != g.Key)) 
     .Select(g => g.ToArray()) 
     .Merge() 
     .Subscribe(groupedItems => 
     { 
      Console.WriteLine("{0} - {1}", groupedItems.First(), groupedItems.Count()); 
     }); 

.Publish().RefCount().GroupByUntilオペレータでのクロージングシーケンスのために必要とされています。

関連する問題