11

假设我有两个可选的 Ints(都可以是 Some 或 None):

val one : Option[Int] = Some(1)
val two : Option[Int] = Some(2)

我的问题如下:是否有任何智能方法可以使用 Scalas 出色的收集方法对它们进行求和?我意识到我可以将它们合并到一个集合中,flattenreduceLeftOption像这样使用:

(one :: two :: Nil).flatten.reduceLeftOption(_ + _)     // Some(3)

但是,上述解决方案意味着创建一个新系列,并生活在一个富裕而发达的世界中,这需要我可能沉浸在所有其他第一世界活动中的时间。在一个编程对像我们这样的程序员来说越来越奢侈的世界里,必须有一个或多个豪华的第一世界答案,对吧?

编辑:所以为了说明问题,这里有一些例子:

如果one = Some(1)并且two = Some(2)我们应该有 Some(3)

如果我们应该有 Some(1 one = Some(1))two = None

如果我们应该有 Some(2 one = None)two = Some(2)

如果两者都onetwoNone 我们应该没有,因为两者onetwo不能正确求和。

希望澄清事情:-)

4

4 回答 4

24
for (x <-one; y <- two) yield x+y

或者可读性较差但严格等效的:

one.flatMap{x=>two.map(x+_)}

更新:正如您的最新编辑非常清楚的None那样,当两个输入选项都是None. 在这种情况下,我认为在简单性方面不会比您已经使用的更好。我可以缩短一点,但总的来说是一样的:

(one ++ two).reduceOption(_ + _)
于 2013-05-01T14:04:18.027 回答
15

强制性 scalaz 答案是使用 scalaz Option monoid:

scala> one |+| two
res0: Option[Int] = Some(3)

它会做你想做的关于无:

scala> two |+| None
res1: Option[Int] = Some(2)

scala> none[Int] |+| none[Int]
res2: Option[Int] = None

none 方法是 scalaz 中的一种方法,它有助于类型推断,因为None <: Option[Nothing]它不是返回 a Option[Int],而是 Some 中的一个类似方法,它为任何给定的 A 返回 Option[A] 而不是 Some[A]:

scala> 1.some |+| 2.some
res3: Option[Int] = Some(3)
于 2013-05-01T14:08:00.473 回答
6

怎么样:

one.map(_ + two.getOrElse(0)).orElse(two)
于 2013-05-01T17:04:27.063 回答
0

你可以试试这个:

for( x <- one.orElse(Some(0)); y <- two.orElse(Some(0))) yield x+y
于 2013-05-01T14:04:24.167 回答