Reactor: как получить плоский кортеж после использования zipWhen с другим кортежем?

Когда я связываю несколько вызовов zipWhen, результатом будет Tuble2<Tuple2<Foo, Bar>, Bam> вместо Tuple3<Foo, Bar, Bam>. Это ухудшается с каждым последующим zipWhen.

Пример:

val getFoo()
  .zipWhen { foo ->
    getBar(foo)
  }
  .zipWhen { fooBar -> 
    getBam(fooBar.t1, fooBar.t2)
  }
  .doOnNext { fooBarBam ->
    log.debug { "foo: ${fooBarBam.t1.t1}" }
    log.debug { "bar: ${fooBarBam.t1.t2}" }
    log.debug { "bam: ${fooBarBam.t2}" }
  }

Какой самый элегантный и многоразовый способ получить Tubple3 в doOnNext?


person Rüdiger Schulz    schedule 20.10.2020    source источник


Ответы (2)


Самый очевидный способ выставить себя на голосование:

  .map {
    Tuples.of(it.t1.t1, it.t1.t2, it.t2)
  }

и извлечение функции.

fun <T1, T2, T3> flatTuple(t: Tuple2<Tuple2<T1, T2>, T3>): Tuple3<T1, T2, T3> =
    Tuples.of(t.t1.t1, t.t1.t2, t.t2)

// ...

  .map { flatTuple(it) }

person Rüdiger Schulz    schedule 20.10.2020

Что вы можете сделать, так это использовать zipWhen с комбинатором, например:

getFoo()
.zipWhen {foo -> getBar(foo) }
.zipWhen({ t -> getBam(t.t1, t.t2) }, {a, b -> Tuples.of(a.t1, a.t2, b)})
.doOnNext { fooBarBam ->
   log.debug { "foo: ${fooBarBam.t1}" }
   log.debug { "bar: ${fooBarBam.t2}" }
   log.debug { "bam: ${fooBarBam.t3}" }
}
person JEY    schedule 20.10.2020