按属性匹配两个无序流,RxJava,RxAndroid

时间:2016-10-21 04:52:24

标签: java android rx-java

有两个流,如下所示

Stream 1: A -- B -- C -- D
Stream 2: 3 -- 1 -- 2 -- 4

我想输出

Output: A1 -- B2 -- C3 -- D4

OR

Output: 3C -- 2B -- 1A -- 4D

每个字母与字母表中的位置相匹配。 我尝试过使用操作符.zip.combineLatest,但没有得到我正在寻找的结果。

事实上,这实际上是我问题的简化。 A,B和C是具有1,2或3等属性的对象。所以我可以做A.position() = 1

之类的事情。

是否有专门解决我的问题的运算符,或者我是否必须使用哈希映射并自己匹配这些对象?

提前致谢。

3 个答案:

答案 0 :(得分:0)

使用Observable.toSortedList,如下所示:

Observable<Data> s1 = Observable.from(new Data[]{new Data(3), new Data(1), new Data(2), new Data(4)});
Observable<String> s2 = Observable.from(new String[]{"A", "B", "C", "D"});

Observable.zip(
        s1.toSortedList(this::compare).flatMap(Observable::from),
        s2,
        (d, s) -> s + d.number
).subscribe(s -> {
    //Output: A1 -- B2 -- C3 -- D4
});

compare方法:

private Integer compare(Data a, Data b) {
    return a.number.equals(b.number) ? 0 : (a.number < b.number ? -1 : 1);
}

Data上课:

class Data {
    private final Integer number;

    Data(Integer number) {
        this.number = number;
    }
}

答案 1 :(得分:0)

我会在另一个流上使用.groupBy(key)在一个流上尝试类似.flatMap()的东西,这将生成Observable&lt; GroupedObservable&lt; YourType&gt;&gt;

或在其他流上使用.toMap()或.toMultimap(),这将生成Observable&lt; Map&lt; K,Collection&lt; T&gt;&gt;&gt;

不确定您是否期望特定订单

答案 2 :(得分:0)

您可以使用rxjava-extras 0.8.0.3(或更新版本,如果可用)中经过单元测试的match运算符。该工件发布在Maven Central上。

将其添加到您的pom.xml:

<dependency>
  <groupId>com.github.davidmoten</groupId>
  <artifactId>rxjava-extras</artifactId>
  <version>0.8.0.3</version>
</dependency>

示例:

Observable<Integer> a = Observable.just(1, 2, 4, 3);
Observable<Integer> b = Observable.just(1, 2, 3, 5, 6, 4);
Obs.match(a, b,
     x -> x, // key to match on for a
     x -> x, // key to match on for b
     (x, y) -> x // combiner
    )
   .forEach(System.out::println);

输出:

1
2
4
3