14

这个问题与这个问题相反。

val x = Some((1, 2))
val (y: Option[Int], z: Option[Int]) = ???

纯 Scala 答案和 Scalaz 答案都是有帮助的。

4

5 回答 5

11

我实际上认为您的答案非常清楚,但是由于您提到了 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))

您应该能够编写简单x.unzip的.OptionIterable(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))

2014年的我,你在想什么?

于 2014-01-30T17:29:49.247 回答
8

根据吉姆的回答,但语法有些人可能会觉得更容易阅读:

val x = Some(1 -> 2)
val (y, z) = x map {case (a,b) => Some(a) -> Some(b)} getOrElse (None -> None)
于 2014-01-30T18:09:34.950 回答
7

我能想到的最好的方法如下,但对我来说它看起来很愚蠢:

val x = Some((1, 2))
val (y, z) = x map {x => (Some(x._1), Some(x._2)) } getOrElse (None, None)
于 2014-01-30T17:11:44.140 回答
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)

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

于 2019-02-08T23:19:43.707 回答
5

正如猫 gitter 频道上的 Rob Norris 所建议的,您可以通过调用以下命令对猫执行此操作.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))

赋值中的类型注释x是相关的;隐式作用于Optionnot 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

separate由提供cats.MonadCombine

于 2018-05-08T17:33:52.117 回答