代码之家  ›  专栏  ›  技术社区  ›  developer_hatch

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

  •  0
  • developer_hatch  · 技术社区  · 7 年前

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

    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 回复  |  直到 7 年前
        1
  •  5
  •   FunctionalWannabe    7 年前

    也可以尝试以下操作:

    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 报告为 没有一个 ; 否则,如果定义了所有值,则会得到一个 Some 包含元素的总和。如果列表为空,则您将获得 Some(0) 因此。

        2
  •  3
  •   developer_hatch    7 年前

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

    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的上下文中。

        3
  •  1
  •   Mahesh Chand    7 年前

    首先使用forall检查是否定义了所有值,如果没有定义,则应用fold获得总和。

    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>
    
        4
  •  0
  •   JPotts    7 年前

    你可以这样做,然后返回一个 Int 也这也避免了在 List 多次。

    val foo = List(Some(1), Some(2), None, Some(3))
    
    foo.foldLeft(0)((acc, optNum) => acc + optNum.getOrElse(0))
    
        5
  •  0
  •   user unknown    7 年前

    只是:

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

    甚至

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