0

By using Observer, I'm trying to build the code, which:

1.Generate some (random) values;

2.Combine this values;

3.If someone combined value exceed the threshold, the value have to be passed to another handler. So I expect the resulted value to be returned for further usage

My code:

 //generate
 val o: Observable[Int] = Observable.repeatEval(Random.nextInt(10))

 //handle 
 val f = o.foldLeft(0) { (acc, el) =>
if (acc < 15) {
  el + acc
} else {
  println("handled " + acc)
  acc
 }
}
//use handled
.flatMap{res =>
          println("mapped " + res + 1)
          Observable(res + 1)
}

But nothing passed to the flatMap-method. The output is following for example:

0
3
7
11
12
handled 20

What am I doing wrong?

Jelly
  • 972
  • 1
  • 17
  • 40
  • 1
    Do you want that each time you surpass the threshold to pass that value to the next stage and restart the `acc` to `0` to keep accumulating until the next value, or do you want to halt at the first element and just emit a singleton `Observable`? – Luis Miguel Mejía Suárez Dec 28 '22 at 13:21
  • The first variant: restart the acc to 0 to keep accumulating until the next value – Jelly Dec 28 '22 at 13:54

1 Answers1

1

You want to use mapAccumulate + collect instead.

def groupWhile[A, B](o: Observable[A], s: B)(op: (B, A) => B)(predicate: B => Boolean): Observable[B] =
  o.mapAccumulate(seed = s) {
    case (b, a) =>
      val bb = op(b, a)
      if (predicate(bb)) (bb, None) else (s, Some(bb))
  } collect {
    case Some(b) => b
  }

Use it like:

// Generate.
val o: Observable[Int] = Observable.repeatEval(Random.nextInt(10))

// Handle.
val f = groupWhile(o, 0)((acc, i) => acc + i)(r => r <= 15)

// Use handled.
f.mapEval { x =>
 val res = x + 1
 Task(println("Mapped: ${res}")).as(res)
}

As I always say, the Scaladoc is your friend.