krisk
krisk

Reputation: 237

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.

Upvotes: 8

Views: 18989

Answers (4)

EpicPandaForce
EpicPandaForce

Reputation: 81569

Apparently to join two lists into one list, you can do Observable.concat() on their Observable.from()s and then call Observable.toList().

RealmResults<Cat> equalTo;
RealmResults<Cat> beginsWith;

@Override
public void onViewRestored() {
    compositeSubscription = new CompositeSubscription();
    equalTo = realm.where(Cat.class).equalTo("field", filterString).findAllSorted("field");
    beginsWith = realm.where(Cat.class).beginsWith("field", filterString).findAllSorted("field");
    compositeSubscription.add(realm.asObservable()
            .switchMap(new Func1<Realm, Observable<Cat>>() {
                @Override
                public Observable<Cat> call(Realm realm) {
                    return Observable.concat(Observable.from(equalTo), Observable.from(beginsWith));
                }
            })
            .toList()
            .subscribe(cats -> {
                // update adapter with List<Cat>
            }));

Upvotes: 0

Gofurs
Gofurs

Reputation: 53

    Observable<List<String>> query1(){
        List<String> s = new ArrayList<>();
        s.add("1");s.add("1");s.add("1");
        return Observable.just(s);
    }
    Observable<List<String>> query2(){
        List<String> s = new ArrayList<>();
        s.add("1");s.add("1");s.add("1");
        return Observable.just(s);
    }
    void HelloRx(){
        Map<String,String> map2=new LinkedHashMap<>();//pick the result you want to return  Here !
        Observable.zip(query1(),//Observable Method 1
                query2(),//Observable Method 2
                (result1,result2)->{
                    for(String s : result1){//result1 is the value returned by query1 , result2 ...u know.
                        //do whatever you want
                        //map.put(......)
                    }
                    return null;
                })
                .subscribeOn(BackgroundSchedulers.getMultiThreadInstance())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnCompleted(() -> {
                   //Do Something when finish for example transmit data to your adapter
                })
                .subscribe();
    }

Upvotes: 0

ihuk
ihuk

Reputation: 1344

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

Upvotes: 31

rocky
rocky

Reputation: 5004

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

Upvotes: 1

Related Questions