2016-09-15 7 views
2

私は、定期的な要素のリストを持っていると言う:RxはGROUP BYのCOUNTに相当しますか?

Observable<String> source = Observable.just("A", "B", "A", "C", "C", "A"); 

私は、彼らが表示された回数と一緒にその値によってグループにそれらをしたいと思いますので、出力はペアのようになります。

{"A", 3}, {"B", 1}, {"C", 2} 

基本的にSELECT x, COUNT(1) GROUP BY x;

のようなSQL文の同等は、私は彼らにGROUPBYを呼び出すためとしてのみ、これまで得た:

source.groupBy(x -> x, x -> 1) 

しかし、これはストリームをGroupedObservablesに変換するので、それらを使って移動する方法の良い例は見つかりませんでした。私はreduce()を試しましたが、groupBy()の後、GroupedObservablesを減らしたいのであって、各グループ内の要素ではないので、ここではうまくいきません。

これはGroupedObservablesで可能ですか?希望の結果を達成する他の方法も可能ですか?

+1

あなたが熱い観測可能性を持っているか、この計算を行うことができない「OnComplete」シグナルを持たない場合は、理解していますか? – Enigmativity

+0

いいえ、私はそれについては考えていませんでしたが、分かりやすいようです、ありがとうございます。実際には、リスト全体が要素ごとにではなく、私の場合は(私は質問のコードを簡略化しています)、私はそれが問題ではないと思います。 –

+0

はい、しかし、それがすべての値を放出するコールドオブザーバブルなら、Rxは必要ありません。何のためにこれをしようとしていますか? – Enigmativity

答えて

8

次のコード

source.groupBy(val -> val) 
    .flatMap(
     gr -> gr.count() 
       .map(count -> new Pair<>(gr.getKey(), count) 
    ) 
).subscribe(System.out::println); 

がプリントアウトになります。

A=3 
B=1 
C=2 
+0

本当にエレガントな、ありがとう! –

1
Observable<String> source = Observable.just("A", "B", "A", "C", "C", "A"); 
    Observable<KeyValue<String, Integer>> countStream = source 
      .groupBy(val -> val) 
      .flatMap(obs -> obs.count().flatMap(cnt -> Observable.just(new KeyValue<>(obs.getKey(), cnt)))); 

    private static class KeyValue<K, V> { 

    private final K key; 
    private final V val; 

    public KeyValue(K key, V val) { 
     this.key = key; 
     this.val = val; 
    } 

    public K getKey() { 
     return key; 
    } 

    public V getVal() { 
     return val; 
    } 
} 
1

別の方法を以下に示すように、collect又はcollectInto方法を使用することです。ところで

Observable<String> source = Observable.just("A", "B", "A", "C", "C", "A"); 

source.collectInto(new HashMap<String, MutableInt>(), (map, elem) -> { 
    if (map.containsKey(elem)) { 
    map.get(elem).increment(); 
    } else { 
    map.put(elem, new MutableInt(1)); 
    } 

}).subscribe(System.out::println); 

我々はReactorを使用していた場合には多数のグループの場合には、GROUPBY後flatMapがハングアップしますので、collectは、これを行うことを示唆する方法です。 GROUPBYは、グループの低カーディナリティで最適に動作するので、それに応じてkeyMapper機能を選択したことをjavadoc of Reactor

noteから


特に、基準が大量のグループを生成する場合、グループが適切にダウンストリームで消費されないと(たとえば、maxConcurrencyパラメータが低すぎるflatMapによって)ハングする可能性があります。

これに関連するgithub issueもあります。

関連する問題