Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android RxJava joining lists

Trying to understand all that RxJava stuff. I was doing following example:

private Observable<List<String>> query1() {
    List<String> urls = new ArrayList<>();
    urls.add("1");
    urls.add("2");
    urls.add("3");
    urls.add("4");

    return Observable.just(urls);
}

private Observable<List<String>> query2() {
    List<String> urls = new ArrayList<>();
    urls.add("A");
    urls.add("B");
    urls.add("C");
    urls.add("D");

    return Observable.just(urls);
}

and then tried to join two lists:

 Observable.zip(
            query1(),
            query2(),
            new Func2<List<String>, List<String>, Observable<String>>() {
                @Override
                public Observable<String> call(List<String> a1, List<String> a2) {
                    List<String> list = new ArrayList<>();
                    list.addAll(a1);
                    list.addAll(a2);
                    return Observable.from(list);
                }
            })
            .subscribe(new Action1<String>() {  // <-- It says, cannot resolve method subscribe
                @Override
                public void call(String string) {
                    String text = testTextView.getText().toString();
                    testTextView.setText(text + "\n" + string);
                }
            });

What I'm doing wrong? I was expecting to get in my view 1 2 3 4 A B C D

EDIT1 I ended with the following answer:

    Observable.zip(
            query1(),
            query2(),
            new Func2<List<String>, List<String>, List<String>>() {
                @Override
                public List<String> call(List<String> a1, List<String> a2) {
                    List<String> list = new ArrayList<>();
                    list.addAll(a1);
                    list.addAll(a2);
                    return list;
                }
            })
            .flatMap(new Func1<List<String>, Observable<String>>() {
                @Override
                public Observable<String> call(List<String> urls) {
                    return Observable.from(urls);
                }
            })
            .subscribe(new Action1<String>() {
                @Override
                public void call(String string) {
                    String text = testTextView.getText().toString();
                    testTextView.setText(text + "\n" + string);
                }
            });

EDIT2 concat solution as suggested by ihuk would be much better in this case. Appreciate for all the answers.

like image 433
krisk Avatar asked Mar 03 '15 22:03

krisk


2 Answers

I believe the operators you are looking for are concat or merge.

Concat will emit the emissions from two or more Observables without interleaving them.

Merge on the other hand will combine multiple observables by merging their emissions.

For example:

    String[] numbers = {"1", "2", "3", "4"};

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

    Observable<String> query1 = Observable.from(numbers).delay(1, TimeUnit.SECONDS);
    Observable<String> query2 = Observable.from(letters);

    Observable
            .concat(query1, query2)
            .subscribe(s -> {
                System.out.printf("-%s-" + s);
            });

Will print -1--2--3--4--a--b--c--d-. If you replace concat with merge the result will be -a--b--c--d--1--2--3--4-.

Zip operator will combine multiple Observables together via specified function. For example

    Observable
            .zip(query1, query2, (String n, String l) -> String.format("(%s, %s)", n, l))
            .subscribe(s -> {
                System.out.printf("-%s-", s);
            });

Will output -(1, a)--(2, b)--(3, c)--(4, d)-.

like image 189
ihuk Avatar answered Sep 30 '22 23:09

ihuk


thats because you are trying to return Observable from zip function, but then you pass Action<String>

Observable.zip(
            query1(),
            query2(),
            new Func2<List<String>, List<String>, List<String>>() {
                @Override
                public List<String> call(List<String> a1, List<String> a2) {
                    List<String> list = new ArrayList<>();
                    list.addAll(a1);
                    list.addAll(a2);
                    return list;
                }
            })
            .subscribe(
                    (string)-> System.out.println(string)
            );
like image 28
hi_my_name_is Avatar answered Sep 30 '22 22:09

hi_my_name_is