总结两个选项

问题描述 投票:8回答:4

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

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

我的问题如下:有没有任何聪明的方法来使用Scalas精彩的收集方法来总结它们?我意识到我可以将它们合并到一个集合中,flatten它并像这样使用reduceLeftOption

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

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

编辑:所以要拼出来,这里有一些例子:

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

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

如果one = Nonetwo = Some(2)我们应该有一些(2)

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

希望澄清的事情:-)

scala option scala-collections
4个回答
13
投票

强制性scalaz答案是使用scalaz选项monoid:

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

对于None,它会做你想要的事情:

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

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

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

scala> 1.some |+| 2.some
res3: Option[Int] = Some(3)

17
投票
for (x <-one; y <- two) yield x+y

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

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

更新:由于您的最新编辑非常清楚,当输入选项都是None时,您只需要一个None作为结果。在这种情况下,我不认为你在简单性方面会比你已经使用的更好。我可以缩短一点但总体来说这是相同的:

(one ++ two).reduceOption(_ + _)

5
投票

怎么样:

one.map(_ + two.getOrElse(0)).orElse(two)

0
投票

你可以试试这个:

for( x <- one.orElse(Some(0)); y <- two.orElse(Some(0))) yield x+y
© www.soinside.com 2019 - 2024. All rights reserved.