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

Sum list of Option[Int] Scala using fold

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

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

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

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

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

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 作为 case Base,我放了 0,但是有 Option 的上下文。

首先使用forall检查所有值是否定义,如果定义则应用fold求和else None.

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>

也试试这个:

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)

您可以这样做,return 也可以 Int。这也避免了多次迭代 List

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

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

刚刚:

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

甚至

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