使用fold的Option [Int] Scala的总和列表

时间:2017-11-16 14:55:48

标签: scala functional-programming fold

我试图对列表中的所有元素求和,它们的类型为Option [Int],如果其中任何一个为None,则整个结果为None,如果所有都是Some(value),我想要所有的总和他们:

val ls = List(Some(2), Some(5), Some(4), Some(1))

ls.fold(None)((rs,x) => for(n <- x; m <- rs) yield {n+m})

但无论如何,我总是得到无。

5 个答案:

答案 0 :(得分:4)

还试试这个:

val ls = List(Some(2), Some(5), Some(4), Some(1))
val sum = ls.foldLeft(Option(0))((so, io) => so.flatMap(s => io.map(s + _)))

如果列表中的任何单个值为None,则sum报告为None;否则 - 如果定义了所有值 - 您将获得包含元素总和的Some。如果列表为空,那么您将获得Some(0)作为结果。

答案 1 :(得分:1)

我意识到我的错误是什么,这是折叠中的基本情况:

val ls = List(Some(2), Some(5), Some(4), Some(1))

ls.fold(Some(0))((rs,x) => for(n <- x; m <- rs) yield {n+m})

而不是None作为Base的情况,我把0,但是使用Option的上下文。

答案 2 :(得分:1)

首先使用forall检查是否定义了所有值,然后应用fold来获取sum,如果已定义,则为无。

scala> val ls = List(Some(2), Some(5), Some(4), Some(1))
ls: List[Some[Int]] = List(Some(2), Some(5), Some(4), Some(1))

scala> if(ls.forall(_.isDefined)) Some(ls.flatten.foldLeft(0){_ + _ }) else None
res22: Option[Int] = Some(12)

scala> val ls = List(Some(2), None,Some(5), Some(4), Some(1),None)
ls: List[Option[Int]] = List(Some(2), None, Some(5), Some(4), Some(1), None)

scala> if(ls.forall(_.isDefined)) Some(ls.flatten.foldLeft(0){_ + _ }) else None
res23: Option[Int] = None

scala>

答案 3 :(得分:0)

您可以执行此操作并返回Int。这也避免了多次迭代List

val foo = List(Some(1), Some(2), None, Some(3))

foo.foldLeft(0)((acc, optNum) => acc + optNum.getOrElse(0))

答案 4 :(得分:0)

只需:

ls.foldLeft (0) (_ + _.getOrElse (0))

甚至

(0 /: ls) (_ + _.getOrElse (0))