Scala: Producing the intermediate results of a fold

前端 未结 4 989
忘了有多久
忘了有多久 2020-12-28 08:52

I\'ve come across the problem of maintaining a state throughout a map operation several times. Imagine the following task:

Given a List[Int], map each element to the

相关标签:
4条回答
  • You're trying to compute the sequence of partial sums.

    The general operation for computing such accumulations is not fold but scan, though scan is expressible through fold in the way you showed (and fold is actually the last element of the list produced by scan).

    As to Scala, I'll give this example

    scala> scanLeft(List(1,2,3))(0)(_ + _)
    res1: List[Int] = List(0, 1, 3, 6)
    
    0 讨论(0)
  • 2020-12-28 09:31

    The scan answers are the best ones, but it's worth noting that one can make the fold look nicer and/or be shorter than in your question. First, you don't need to use pattern matching:

    a.foldLeft(List(0)){ (l,i) => (l.head + i) :: l }.reverse
    

    Second, note that foldLeft has an abbreviation:

    (List(0) /: a){ (l,i) => (l.head + i) :: l }.reverse
    

    Third, note that you can, if you want, use a collection that can append efficiently so that you don't need to reverse:

    (Vector(0) /: a){ (v,i) => v :+ (v.last + i) }
    

    So while this isn't nearly as compact as scanLeft:

    a.scanLeft(0)(_ + _)
    

    it's still not too bad.

    0 讨论(0)
  • 2020-12-28 09:31

    I like to fold around just like everybody else, but a less FP answer is very concise and readable:

     a.map{var v=0; x=>{v+=x; v}}
    
    0 讨论(0)
  • 2020-12-28 09:43

    @Dario gave the answer, but just to add that the scala library provides scanLeft:

    scala> List(1,2,3).scanLeft(0)(_ + _)
    res26: List[Int] = List(0, 1, 3, 6)
    
    0 讨论(0)
提交回复
热议问题