Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is an idiomatic way to filter out Either Left in an akka stream?

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.

like image 339
Stoecki Avatar asked Jun 29 '18 07:06

Stoecki


2 Answers

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.

like image 164
lslah Avatar answered Oct 11 '22 09:10

lslah


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.

like image 29
Yuval Itzchakov Avatar answered Oct 11 '22 07:10

Yuval Itzchakov