如何将选项元组转换为Scala中的选项元组?

Jim*_*ker 12 scala tuples scala-option

这个问题与这个问题相反.

val x = Some((1, 2))
val (y: Option[Int], z: Option[Int]) = ???
Run Code Online (Sandbox Code Playgroud)

纯Scala答案和Scalaz答案都很有帮助.

Tra*_*own 10

我实际上认为你的答案非常明确,但是既然你提到Scalaz,这个操作被称为unzip:

scala> import scalaz._, std.option._
import scalaz._
import std.option._

scala> val x: Option[(Int, Int)] = Some((1, 2))
x: Option[(Int, Int)] = Some((1,2))

scala> Unzip[Option].unzip(x)
res0: (Option[Int], Option[Int]) = (Some(1),Some(2))
Run Code Online (Sandbox Code Playgroud)

你应该能够简单地写x.unzip,但不幸的是标准库中的可怕的隐式转换Option,以Iterable将在第一踢,你会与结束(Iterable[Int], Iterable[Int]).


回顾一年后:实际上可以用Scalaz做到这一点UnzipPairOps:

scala> import scalaz.std.option._, scalaz.syntax.unzip._
import scalaz.std.option._
import scalaz.syntax.unzip._

scala> val x: Option[(Int, Int)] = Some((1, 2))
x: Option[(Int, Int)] = Some((1,2))

scala> x.unfzip
res0: (Option[Int], Option[Int]) = (Some(1),Some(2))
Run Code Online (Sandbox Code Playgroud)

你在想什么,2014年我?


Kev*_*ght 8

根据Jim的回答,但有一些语法可能会更容易阅读:

val x = Some(1 -> 2)
val (y, z) = x map {case (a,b) => Some(a) -> Some(b)} getOrElse (None -> None)
Run Code Online (Sandbox Code Playgroud)


Jim*_*ker 6

我能想到的最好的是以下内容,但对我来说看起来很傻:

val x = Some((1, 2))
val (y, z) = x map {x => (Some(x._1), Some(x._2)) } getOrElse (None, None)
Run Code Online (Sandbox Code Playgroud)

  • 我认为它根本不傻,它描述了你想要做的事情,我可能会用`x map {case(fst,snd)=>替换`x map {x => ...` `避免调用`_1`和`_2`. (4认同)

Xav*_*hot 6

首先Scala 2.13,标准库中提供了这种确切的行为Option#unzip

// val x: Option[(Int, String)] = Some(1, "hello")
x.unzip
// (Some(1), Some("hello"))
val (y, z) = x.unzip
// y: Option[Int] = Some(1)
// z: Option[String] = Some("hello")

// val x: Option[(Int, String)] = None
x.unzip
// (None, None)
Run Code Online (Sandbox Code Playgroud)

另请注意 3 元素元组的等效项:Option#unzip3.


Mar*_* T. 5

正如 Rob Norris 在猫 gitter 频道上所建议的那样,您可以通过调用以下命令对猫执行此操作.separate

@ import cats.implicits._
import cats.implicits._

@ val x: Option[(Int, Int)] = Some((1, 2))
x: Option[(Int, Int)] = Some((1, 2))

@ x.separate
res6: (Option[Int], Option[Int]) = (Some(1), Some(2))
Run Code Online (Sandbox Code Playgroud)

赋值中的类型注解x是相关的;隐式操作Optionnot on Some

@ val x = Some((1, 2))
x: Some[(Int, Int)] = Some((1, 2))

@ x.separate
cmd2.sc:1: value separate is not a member of Some[(Int, Int)]
val res2 = x.separate
Run Code Online (Sandbox Code Playgroud)

separate 由提供 cats.MonadCombine