web-dev-qa-db-ja.com

Rx Observableを複数のストリームに分割し、個別に処理します

これが私が達成しようとしていることの写真です。

--a-b-c-a--bbb--a

割る

--a ----- a ------- a->ストリーム

---- b ------ bbb ----> bストリーム

------ c -----------> cストリーム

次に、できること

a.subscribe()
b.subscribe()
c.subscribe()

これまでのところ、私が見つけたすべてのものはgroupBy()を使用してストリームを分割しましたが、すべてを単一のストリームに折り畳み、同じ関数ですべて処理しました。私がしたいのは、各派生ストリームを異なる方法で処理することです。

私が今それをやっている方法は、たくさんのフィルターをすることです。これを行うためのより良い方法はありますか?

34
Brandon Bil

ObservablesgroupByから折りたたむ必要はありません。代わりにそれらをサブスクライブできます。

このようなもの:

    String[] inputs= {"a", "b", "c", "a", "b", "b", "b", "a"};

    Action1<String> a = s -> System.out.print("-a-");

    Action1<String> b = s -> System.out.print("-b-");

    Action1<String> c = s -> System.out.print("-c-");

    Observable
            .from(inputs)
            .groupBy(s -> s)
            .subscribe((g) -> {
                if ("a".equals(g.getKey())) {
                    g.subscribe(a);
                }

                if ("b".equals(g.getKey())) {
                    g.subscribe(b);
                }

                if ("c".equals(g.getKey())) {
                    g.subscribe(c);
                }
            });

ステートメントが見苦しい場合でも、少なくとも各ストリームを個別に処理できます。たぶんそれらを回避する方法があります。

15
ihuk

円グラフのように簡単で、filterを使用するだけです

Scalaの例

import rx.lang.scala.Observable

val o: Observable[String] = Observable.just("a", "b", "c", "a", "b", "b", "b", "a")
val hotO: Observable[String] = o.share
val aSource: Observable[String] = hotO.filter(x ⇒ x == "a")
val bSource: Observable[String] = hotO.filter(x ⇒ x == "b")
val cSource: Observable[String] = hotO.filter(x ⇒ x == "c")

aSource.subscribe(o ⇒ println("A: " + o), println, () ⇒ println("A Completed"))

bSource.subscribe(o ⇒ println("B: " + o), println, () ⇒ println("B Completed"))

cSource.subscribe(o ⇒ println("C: " + o), println, () ⇒ println("C Completed"))

ソースオブザーバブルがホットであることを確認する必要があります。最も簡単な方法はshare itです。

36

あなたの質問はrx-Javaとrxjsの両方でタグ付けされているので、rxjsの答えを投稿すると思いました。

同じ問題があり、パーティションを使用して問題を解決しました。基本的には次のとおりです。

import { from } from 'rxjs';
import { partition } from 'rxjs/operators';

const source = from([{category: 1, value: 10}, {category: 2, value: 20}]);

const categories = source.pipe(partition(v => v.category));
for (c of categories) {
    c.pipe(
        // etc
    ).subscribe(val => {
        // etc
    });
}

注:この例をテストしませんでした。問題が見つかった場合は、投稿を編集してください。ありがとう!

この例を公式ドキュメントから言い換えました: https://www.learnrxjs.io/operators/transformation/partition.html

0
James Watkins