假设我有两个可选的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 = None
和two = Some(2)
我们应该有一些(2)
如果one
和two
都是None
,我们应该为无,因为one
或two
都无法正确汇总。
希望澄清事情: - )
答案 0 :(得分:17)
for (x <-one; y <- two) yield x+y
或者可读性较差但严格等同:
one.flatMap{x=>two.map(x+_)}
更新:由于您的最新修改非常明确,因此当输入选项均为None
时,您只需要None
作为结果。在这种情况下,我不认为你在简单性方面会比你已经使用的更好。我可以缩短一点,但总的来说这是相同的:
(one ++ two).reduceOption(_ + _)
答案 1 :(得分:13)
强制性scalaz的回答是使用scalaz Option 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]为任何给定A而不是某些[A]:
scala> 1.some |+| 2.some
res3: Option[Int] = Some(3)
答案 2 :(得分:5)
怎么样:
one.map(_ + two.getOrElse(0)).orElse(two)
答案 3 :(得分:0)
你可以试试这个:
for( x <- one.orElse(Some(0)); y <- two.orElse(Some(0))) yield x+y