如何在Scala中使用reduce函数?有这样的内置功能吗? 我已经实现了一个程序来查找scala中的字数。
object count {
def main(args: Array[String]) {
val fruits = List("apple", "apple", "orange", "apple", "mango", "orange")
val word = fruits.flatMap(_.split("\n"))
val Map = word.map(word => (word,1)).groupBy(_._1)
val reduce = Map.map(word => (word._1,word._2.foldLeft(0)((sum,c) => sum+ c._2)))
println(reduce) }}
如何用reduce函数替换foldleft?
答案 0 :(得分:14)
上面的整个示例应该像这样实现
fruits groupBy(word => word) mapValues(_.size)
或像这样替换折叠
val reduce = Map.map(word => (word._1,word._2.size))
但是如果你绝对肯定必须在相同的代码中使用reduce,那就是这样的
val reduce = Map.map(word => (word._1,word._2.map(_=>1).reduce(_+_)))
答案 1 :(得分:2)
您的示例可以更简单地完成,如下所示:
> fruits.groupBy(identity).mapValues(_.size)
res176: Map[String, Int] = Map("mango" -> 1, "orange" -> 2, "apple" -> 3)
但是,如果要并行化并使用MapReduce模式,reduce在这里很有用。如果不进行并行化,则只需按顺序减少一个列表(1,1,1,1 ...)。比较:
> List(1,1,1,1,1,1,1).reduce{(a,b) => println(s"$a+$b=${a+b}"); a + b}
1+1=2
2+1=3
3+1=4
4+1=5
5+1=6
6+1=7
res187: Int = 7
使用并行化版本(请注意par
方法):
> List(1,1,1,1,1,1,1).par.reduce{(a,b) => println(s"$a+$b=${a+b}"); a + b}
1+1=2
1+1=2
1+2=3
1+1=2
2+2=4
3+4=7
res188: Int = 7
您可以通过定义常用的reduceByKey
函数来使用MapReduce模式,如下所示:
implicit class MapReduceTraversable[T, N](val traversable: Traversable[(T, N)]) {
def reduceByKey(f: (N, N) => N) = traversable.par.groupBy(_._1).mapValues(_.map(_._2)).mapValues(_.reduce(f))
}
val fruits = List("apple", "apple", "orange", "apple", "mango", "orange", "apple", "apple", "apple", "apple")
fruits.map(f => (f,1)).reduceByKey(_ + _)
res2: collection.parallel.ParMap[String, Int] = ParMap(orange -> 2, mango -> 1, apple -> 7)
你可以像以前一样调试它:
fruits.map(f => (f,1)).reduceByKey{(a,b) => println(s"$a+$b=${a+b}"); a + b}
1+1=2
1+1=2
2+1=3
3+1=4
4+1=5
5+1=6
6+1=7
res9: Map[String, Int] = Map("mango" -> 1, "orange" -> 2, "apple" -> 7)
答案 2 :(得分:0)
不,没有内置功能,表现得像那样。您可以使用mapValues
代替第二map
来简化它,但没有类似的foldValues
。