Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collect grouped observables' emissions into one list

Tags:

rx-java

I have the following use case (this is of course a contrived example, but once I know the answer, I will be able to port it to a real problem I am to solve):

  1. Get a list of integers.
  2. Group them by the result of the % 4 operation
  3. Collect the each group's elements to lists
  4. Ignore any groups/lists which have fewer elements than 3 elements
  5. Emit a single list, whose elements are the lists created in step #3

Here is my current code:

    Observable
            .from(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12))
            .groupBy(item -> item % 4)
            .subscribe(groupedObservable -> {
                groupedObservable
                        .toList()
                        .filter(list -> list.size() > 2)
                        .subscribe(result -> {
                            System.out.printf("%d results %s%n", result.size(), result);
                        });
            });

and its output is:

4 results [0, 4, 8, 12]
3 results [2, 6, 10]
3 results [3, 7, 11]

So it prints out how many elements each group has and then the list of elements. I would like the output to be (I actually don't care about the keys):

3 results: [[0, 4, 8, 12], [2, 6, 10], [3, 7, 11]]

i.e. somehow flatten the grouped observables into one list. I fail to do so. For example, adding .flatMap(integers -> Observable.just(integers)) after the filter doesn't change anything, as it just influences each grouped observable, not the whole stream. Is there a way to fulfill my requirements?

like image 876
wujek Avatar asked Jun 14 '15 15:06

wujek


1 Answers

I'm not sure if I've understood you correctly, but based on the desired output here is the code you might be looking for:

public static void main(final String[] args) throws Exception {
    Observable.from(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12))
            .groupBy(item -> item % 4)
            .flatMap(Observable::toList)
            .filter(integers -> integers.size() > 2)
            .toList()
            .subscribe(result -> {
                System.out.printf("%d results %s%n", result.size(), result);
            });
}
like image 125
Vladimir Mironov Avatar answered Sep 24 '22 11:09

Vladimir Mironov