Concat流在任意位置

时间:2015-09-16 21:00:00

标签: reactive-programming rx-java

关于RxJava的另一个问题。我本周着火了。

我有使用RxJava解决以下问题:

我有一个Model个对象流,我将其转换为ViewModel个对象的流。一切都很直接 - 我只使用map运算符,它工作正常。但是我有一个要求 - 有时我需要在满足给定条件的元素之后添加假ViewModel。即:

models:     ---1----2----3----4----5----6----->
                      vvvvvvvvvvvvvvvvv
viewmodels: --A(1)-A(2)-A(3)-A(4)-A(5)-A(6)--->

现在假设我想在viewmodels流中的最后一个奇数之后添加假viewmodel:

result:     --A(1)-A(2)-A(3)-A(4)-A(5)-A(-1)-A(6)--->

我查看了concatMap运算符 - 它允许我使用更多元素扩展给定的流,但我不知道如何添加在任意位置添加新元素的逻辑。

编辑:添加假模型的位置未知。选择“最后奇数”案例作为例子。在实际情况中,我有更复杂的逻辑决定假模型的去向。如果在流

中找不到满足给定标准的项目,则根本不应添加假模型

EDIT2 :为了更加真实,我的ModelViewModel类都包含布尔标志。我们将此标志称为isFinished。在我的情况下,我需要在流中的最后一个“完成”项后添加假viewmodel。如果它们都没有完成 - 不应该添加伪视图模型。所以最终我添加了一个假模型

1 个答案:

答案 0 :(得分:0)

在您的示例中,插入假ViewModel的决定取决于知道流何时完成。最后一个奇数是一个简单的案例来处理使用buffer向前看一点。当流的末尾关闭时,缓冲区的大小不会是3,您可以检查索引以查看您是否处于奇数位置。这应该给你一般的想法,我留给你正确地考虑边缘情况:

modelsWithIndex
    .buffer(3,1)
    .concatMap(list -> {
         if (list.size()==3 || list.get(0).index % 2 == 0)
             return Observable.just(list.get(0).model);
         else  
             return Observable.just(list.get(0).model, createFakeModel());
    });

在Edit2之后,到流末尾的距离似乎可以任意大,因此buffer不是最佳选择。在这种情况下,我会使用rxjava-extras中的Transfomers.toListWhile()。作为参数传递的条件函数将在model.finished返回true时返回false,然后您可以使用.buffer(2,1).flatMap()技巧来检测最后一个列表并返回Observable.just(fakeModel).concatWith(Observable.from(list))或者如果不是,则返回Observable.from(list) { {1}}。