Rx编程,如何在单个observable中将项目与前一个元素结合起来?

时间:2016-06-06 09:43:18

标签: reactive-programming rx-scala

如果我们有可观察的:

1 -> 2 -> 3 -> 4 -> 5 -> ...

如何构建新的observable:

(1, 2) -> (3, 4) -> ...

也许问题要简短,但我真的找不到如何实现。谢谢你

感谢每一个人,我找到了一个方法,并考虑删除var

import java.util.concurrent.TimeUnit

import rx.lang.scala.{Subject, Observable}

import scala.concurrent.duration.Duration
object ObservableEx {
   implicit class ObservableImpl[T](src: Observable[T]) {
     /**
       * 1 -> 2 -> 3 -> 4 ->...
       * (1,2) -> (3,4) -> ...
       */
     def pair: Observable[(T, T)] = {
       val sub = Subject[(T, T)]()
       var former: Option[T] = None //help me to kill it
       src.subscribe(
         x => {
           if (former.isEmpty) {
             former = Some(x)
           }
           else {
             sub.onNext(former.get, x)
             former = None
           }
         },
         e => sub.onError(e),
         () => sub.onCompleted()
       )

       sub
     }
   }
}

object Test extends App {
  import ObservableEx._
  val pair = Observable.interval(Duration(1L, TimeUnit.SECONDS)).pair
  pair.subscribe(x => println("1 - " + x))
  pair.subscribe(x => println("2 - " + x))

  Thread.currentThread().join()
}

我根本不喜欢var,再次感谢!

最后 我有一个轻松的方式,希望可以帮助别人。

 def pairPure[T](src: Observable[T]): Observable[(T, T)] = {
   def pendingPair(former: Option[T], sub: Subject[(T, T)]): Unit = {
     val p = Promise[Unit]
     val subscription = src.subscribe(
       x => {
         if (former.isEmpty) {
           p.trySuccess(Unit)
           pendingPair(Some(x), sub)
         }
         else {
           sub.onNext(former.get, x)
           p.trySuccess(Unit)
           pendingPair(None, sub)
         }
       },
       e => sub.onError(e),
       () => sub.onCompleted()
     )

     p.future.map{x => subscription.unsubscribe()}
   }

   val sub = Subject[(T,T)]()
   pendingPair(None, sub)
   sub
 }

其他答案也很有帮助〜

2 个答案:

答案 0 :(得分:0)

尝试使用groupBy运算符。 祝你好运。

答案 1 :(得分:0)

您可以tumblingBuffercount = 2一起使用Observable Seq长度为2的map,并使用implicit class ObservableImpl[T](src: Observable[T]) { def pair: Observable[(T, T)] = { def seqToPair(seq: Seq[T]): (T, T) = seq match { case Seq(first, second) => (first, second) } src.tumblingBuffer(2).map(seqToPair) } } ,您可以将它们变成对:

seqToPair

请注意,如果源Observable中的元素数量为奇数,则会失败,因此您必须在CREATE TRIGGER TRG_COMPLETE_REMINDER AFTER UPDATE ON reminders FOR EACH ROW BEGIN IF (NEW.complete = 1 AND NEW.recurrence <> 'NONE') THEN INSERT INTO reminders (description, date, userID, complete, recurrence) VALUES (NEW.description, CASE NEW.recurrence WHEN '1 WEEK' THEN NEW.date + INTERVAL 7 DAY WHEN '1 MONTH' THEN NEW.date + INTERVAL 1 MONTH WHEN '3 MONTH' THEN NEW.date + INTERVAL 3 MONTH ELSE NULL END, NEW.userID, 0, NEW.recurrence); END IF; END; 中涵盖此情况。