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

快速代码演示:【只关注reduce和fold从第四点开始看】

object HighLevelFunction extends App {
  val l = List(1, 2, 3, 4, 5)

  //1.map 逐个操作集合里面的每个元素
  l.map((x: Int) => x + 1) //将List内的每个元素(x:Int) + 1
  l.map(x => x + 1)        //scala能帮我们推断出List内每个元素是Int,且只有一个元素时候,括号可以省略
  l.map(_ + 1)             //对List中的任意元素都 + 1
  //遍历
  l.map(_ + 1).foreach(print)    //23456 List[Int]

  println()
  println("-------------")

  //2.在map取出每个元素 + 1的基础上,使用filter过滤出 < 4的数字
  l.map(_ + 1).filter(_ < 4).foreach(print)   //23  List[Int]

  println()
  println("-------------")

  //3.使用take取集合中的前3个元素
  l.take(3).foreach(print)      //123    List[Int]

  println()
  println("-------------")

  //4.reduce
  print(  l.reduce(_ + _)  )  //15     Int  将l集合中的前后元素两两相加 1+2 3+3 6+4 10+5

  println()
  println("-------------")

  //5.reduceLeft = reduce
  print(  l.reduceLeft(_ - _)  )   //-13  1 - 2 - 3 - 4 - 5 = -13

  println()
  println("-------------")

  //6.reduceRight
  print(  l.reduceRight(_ - _)  )  //3   ( 1 - ( 2 - ( 3 - ( 4 - 5 ))))

  println()
  println("-------------")

  //7.fold(第一个括号代表初始值)
  print(  l.fold(0)(_ - _)  )    //-15  0-1-2-3-4-5 = -15

  println()
  println("-------------")

  //8.foldLeft = fold  (0在最左边)
  print(  l.foldLeft(0)(_ - _))  //-15  0-1-2-3-4-5 = -15

  println()
  println("-------------")

  //9.foldRight        (0在最右边)
  print(  l.foldRight(0)(_ - _) ) //3    ( 1 - ( 2 - ( 3 - ( 4 - (5 - 0) ) ) ) )
}

 

 

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

eg:

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

 

c.reduceRight(op)这样的调用将op相继应用到元素,如: 

var b = List(1,2,3,4,5)
val c = b.reduceRight(_ - _)    // ( 1 - ( 2 - ( 3 - ( 4 - 5 ) ) ) )


 
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)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值