2015-01-30 21 views
8

Với đầu vào:.Làm thế nào để chuỗi nhiều phương pháp RxJava của groupby() như groupby() groupby()

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

Tập đoàn số bằng cách lẻ hoặc thậm chí và sau đó bằng cách nhỏ hơn hoặc lớn hơn 5.

Sản lượng mong muốn:

[[1, 3, 5], [2, 4], [6, 8, 10], [7, 9]] 

Thứ tự của đầu ra không bị giới hạn.

bây giờ tôi đang sử dụng phương pháp sau đây:

Observable.range(1, 10) 
    .groupBy(n -> n % 2 == 0) 
    .flatMap((GroupedObservable<Boolean, Integer> g) -> { 
     return Observable.just(g).flatMap(ObservableUtils.<Boolean, Integer>flatGroup()).groupBy(n -> n > 5); 
    }) 
    .subscribe((final GroupedObservable<Boolean, Integer> g) -> { 
     Observable.just(g).flatMap(ObservableUtils.<Boolean, Integer>flatGroup()).forEach(n -> println(g + ": " + n)); 
    }); 

Lưu ý rằng ObservableUtils được viết bởi tôi để đơn giản hóa các mã.

Nhưng tôi không hài lòng với nó vì nó vẫn không đủ ngắn để chỉ đơn giản là chỉ mục tiêu.

gì tôi mong đợi là như sau:

Observable.range(1, 10) 
    .groupBy(n -> n % 2 == 0) 
    .groupBy(n -> n > 5) 
    .subscribe(...); 

Để bây giờ tôi chỉ có thể thu nhỏ nó:

Observable.range(1, 10) 
    .lift(new OperatorGroupByGroup(n -> n % 2 == 0)) 
    .lift(new OperatorGroupByGroup(n -> n > 5)) 
    .subscribe(...); 

tôi vẫn phải viết lớp OperatorGroupByGroup đó là một chút phức tạp chút. Bất kỳ đề xuất để cải thiện?

Trả lời

2

Tôi đã viết một mẫu cho OperatorGroupByGroup rằng dựa trên OperatorGroupBy:

https://github.com/yongjhih/RxJava-GroupByTest

Cách sử dụng:

git clone https://github.com/yongjhih/RxJava-GroupByTest.git 
./gradlew execute 

Nhưng tôi đổi mã thử nghiệm do thực hiện OperatorGroupByGroup tôi:

Observable.range(1, 10) 
    .lift(new OperatorGroupByGroup<Integer, Boolean, Integer>(n -> n % 2 == 0)) 
    .lift(new OperatorGroupByGroup<GroupedObservable<Boolean, Integer>, Boolean, Integer>(n -> n > 5)) 
    .subscribe((final GroupedObservable<Boolean, Integer> g) -> { 
     Observable.just(g).flatMap(ObservableUtils.<Boolean, Integer>flatGroup()).forEach(n -> println(g + ": " + n)); 
    }); 

Tôi nghĩ ai đó sẽ làm tốt hơn.

2

Cố gắng thực hiện theo cách này.

Observables.range(1,10) 
    .groupBy(n -> n % 2 == 0) 
    .flatMap(grp -> grp.groupBy(n -> n > 5).flatMap(grp2 -> grp2.toList())) 
    .subscribe(...) 
1

Tôi có hai đề xuất mà tôi cho là vừa đẹp vừa thanh lịch.

Đầu tiên:

Observable.range(1, 10) 
    .groupBy(n -> n % 2 == 0) 
    .flatMap(g -> g.groupBy(n -> n > 5)) 
    .subscribe(...); 

Đó là gần như tốt như kỳ vọng của bạn, chỉ cần một thêm .flatMap(). Vấn đề duy nhất? Bạn bị mất chìa khóa đầu tiên, nhưng tôi không chắc bạn đang sử dụng những cái đó.

Nhu cầu thứ hai tuyên bố lớp đơn giản Key có thể chứa kết quả của cả hai điều kiện của bạn và thực hiện equals() thích hợp. Nói cách khác là Pair. Sau đó, bạn có thể làm:

Observable.range(1, 10) 
    .groupBy(n -> new Key(n % 2 == 0, n > 5)) 
    .subscribe(...); 

này có nhược điểm là ít composable, như bạn có cả hai điều kiện trong cùng .groupBy() cuộc gọi thay vì xích.Ưu điểm là bạn có thể sử dụng một khóa kết hợp chứa kết quả của cả hai điều kiện của bạn nếu bạn cần chúng.