scala中的reduceLeft,reduceRight,foldLeft,foldRight方法

scala中集合类iterator特质的化简和折叠方法
c.reduceLeft(op)这样的调用将op相继应用到元素,如:
这里写图片描述
eg:

    val a = List(1,7,2,9)
    val a1 = a.reduceLeft(_ - _)//      ((1-7) - 2) - 9 = -17

这里写图片描述
c.foldLeft(0)(_ * _)方法
这里写图片描述

    val a2 = a.foldLeft(0)(_ - _) //    0-1-7-2-9 = -19

对于foldLeft方法还有一种简写,这种写法的本意是让你通过/:来联想一棵树的样子
对/:操作符来说,初始值是第一个操作元本题中是0,:后是第二个操作元a

    val a3 = (0 /: a)(_ - _) //      等价于a.foldLeft(0)(_ - _)

scala同样也提供了foldRight或:\的变体,计算
这里写图片描述

    val a4 = a.foldRight(0)(_ - _)//    1-(7-(2-(9-0))) = -13
    val a5 = (a :\ 0)(_ - _)   //    等价于a.foldRight(0)(_ - _)

好像上面的方法都没什么用,但折叠fold有时候可以代替循环,例如:
统计每个字母中字符串出现的次数

    val frep  = collection.mutable.Map[Char,Int]() //   使用可变集合
//      使用for循环来统计次数
    for(c <- "Mississippi") frep(c) = frep.getOrElse(c, 0)+1
//      使用/: foldLeft()()来统计次数
    val result = (Map[Char,Int]() /: "Mississippi"){
        (m,c) => m + (c -> (m.getOrElse(c, 0)+1))
    }
//      任何while循环都可用fold来代替
    println(frep,result) //(Map(M -> 1, s -> 4, p -> 2, i -> 4),Map(M -> 1, i -> 4, s -> 4, p -> 2))

这是使用fold的步骤:在每一步,将频率映射和新遇到的字母结合在一起,产生一个新的频率映射。这就是折叠:
这里写图片描述
fold的初始值和操作符是分开定义的柯里化参数,这样scala就可以呀根据类型来推断操作符的类型定义。
eg:该函数的初始值是String,因此操作符的类型应该是(String,Int) => String的函数

    val a7 = a.foldLeft("")(_ + _)
    val a8 = a.foldRight("")(_+_)
    val a9 = a.fold(0)(_+_)
    println(a7,a8,a9) //    (1729,1729,19)
发布了60 篇原创文章 · 获赞 76 · 访问量 12万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览