5

I have a stream having a huge bunch of either values in it. I am looking for an itiomatic way to filter out the Either-Left and map on the Either-Right. I want to avoid something like

final case class Foo(x: Either[String, Int], y:Int)

val foos = functionReturningSeqOfFoo()

Source(foos)
  .filter(_.x.isRight)
  .map(foo => (foo.x.right.get, foo.y))
  .map { case (x, y) =>
    doSomethingWith(x, y)
  }
  .runWith(Sink.seq)

This is some a minimal example. Since my stream is very long this is becomming messy and it doesn't feel like a good approach.

Btw the same applies to Option[T] in my case.

Stoecki
  • 585
  • 1
  • 3
  • 16

2 Answers2

4

You can use collect:

Source(foos).collect { case Foo(Right(x), y) => (x, y) }

or directly transforming the tuple using:

Source(foos).collect { case Foo(Right(x), y) => doSomethingWith(x, y) }

collect will drop all objects for which the partial function is not defined.

lslah
  • 556
  • 8
  • 17
2

You're looking for Flow.collect:

Source(eithers)
 .collect { case Foo(Right(x), y) => (x, y) }
 .map { case (x, y) => doSomethingWith(x, y) }
 .runWith(Sink.seq)

collect, similar to the Scala library, applies the partial function to all elements and returns these which yield true for it's isDefined method.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321