SwiftMango
SwiftMango

Reputation: 15304

How to yield multiple values?

I have a for comprehension like:

val ao = Option(1)
val bo = Option(2)
val (x,y) = for (a <- ao; b <- bo) yield (a+b, b+a*2)

However this does not work. For comprehension returns Option[(Int,Int)] but cannot be assigned to individual x and y.

If I do:

val Some((x,y)) = for ...

It causes exception when yield None.

How to achieve this goal? I want x and y to be Option[Int]. I hope to find an elegant solution without using like x._1 or x.getOrElse, or match

Upvotes: 3

Views: 2518

Answers (2)

Simon Groenewolt
Simon Groenewolt

Reputation: 10665

Isn't pattern matching the best way to handle options?

val res = for (a <- ao; b <- bo) yield (a+b, b+a*2)

val (x, y) = res match {
  case Some((x, y)) => (Some(x), Some(y))
  case None => (None, None)
}

Why would that not be considered 'elegant'?

Upvotes: 0

Andrey Tyukin
Andrey Tyukin

Reputation: 44992

It should have been unzip, but unfortunately, unzip returns Lists, not Options. Probably the shortest work-around would be:

val pairOpt = for (a <- ao; b <- bo) yield (a+b, b+a*2)
val (x, y) = (pairOpt.map(_._1), pairOpt.map(_._2))

Upvotes: 3

Related Questions