美文网首页
Scala的foldLeft和foldRight

Scala的foldLeft和foldRight

作者: scandly | 来源:发表于2018-08-13 19:00 被阅读0次

    可以参照对该函数的解析学习scala源码分析的方法

    /:以及:\ 可以看出是foldLeft和foldRight的简写(向左右折叠)

    def /:[B](z: B)(op: (B, A) => B): B = foldLeft(z)(op)

    def :\[B](z: B)(op: (A, B) => B): B = foldRight(z)(op)

    foldLeft

    def foldLeft[B](z: B)(op: (B, A) => B): B = {// 注意:op,op是一个操作,具体什么操作,要看实现

      var result = z

      this.seq foreach (x => result = op(result, x))

        result

    }

    op是一个闭包

    方法接受2个参数,z和op,一个是B类型的参数,一个是返回B类型的函数。

    val listA = List(1,2,3)

    我们可以直接使用:

    scala> listA.foldLeft(0)((sum,i)=>sum+i)

    res26: Int = 6

    可见上面提到的op 就是 sum+i 是一个加的操作

    // sum + i 后又赋值给sum,然后不断的foreach 调用这个op

    这个里面的0其实就是z返回值是Int类型即B类型

    那么可以看出op这个函数返回值也需要是Int类型

    val result = z, 这里其实就是0,x=>result=op(result, x)

    这里我们执行的是sum+i,就是累加了1+2+3=6

    foldRight

    先看下定义:

    def foldRight[B](z: B)(op: (A, B) => B): B =

    reversed.foldLeft(z)((x, y) => op(y, x))

    这里多了一个reversed

    // for internal use

    protected[this] def reversed = {

    var elems: List[A] = Nil

    self.seq foreach (elems :: _)

    elems

    }

    上面就是一个翻转

    在参数做了一个翻转再调用foldLeft

    (x,y) => op(y,x)

    这样写就对了:

    scala> ((1 to 5)).foldRight(100)((i,sum)=>sum-i)

    res49: Int = 85

    总结一下,foldRight就是逆序集合,然后调用foldLeft

    flodLeft的简写 /: 

    如果我写一个累加的程序

    scala> (0/:(1 to 100))(_+_)

    res32: Int = 5050

    其实是等价于

    scala> (1 to 100).foldLeft(0)(_+_)

    res33: Int = 5050

    foldRight的简写 :\

    如果我写一个递减的程序

    scala> ((1 to 5):\100)((i,sum)=> sum-i)

    res51: Int = 85

    相关文章

      网友评论

          本文标题:Scala的foldLeft和foldRight

          本文链接:https://www.haomeiwen.com/subject/kjzubftx.html