Scala - 减少功能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24216479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 06:20:46  来源:igfitidea点击:

Scala - reduce function

scalamapreduceword-count

提问by user2841047

How to use reduce function in Scala? Is there a built in function like that? I have implemented a program to find word count in scala.

如何在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)     }} 

How to replace foldleft with reduce function?

如何用reduce函数替换foldleft?

回答by Azzie

Entire example above should be implemented like this

上面的整个示例应该像这样实现

fruits groupBy(word => word) mapValues(_.size)

or like this as replacement for fold

或者像这样作为折叠的替代品

val reduce = Map.map(word => (word._1,word._2.size))

but if you absolutely positively must use reduce in the same exact code, it would be something like this

但是如果你绝对肯定必须在相同的代码中使用 reduce,它会是这样的

val reduce = Map.map(word => (word._1,word._2.map(_=>1).reduce(_+_)))

回答by David Portabella

your example can be done simpler as follows:

您的示例可以更简单地完成如下:

> fruits.groupBy(identity).mapValues(_.size) 
res176: Map[String, Int] = Map("mango" -> 1, "orange" -> 2, "apple" -> 3)

however, reduce is useful here if you want to parallelize and use the MapReduce pattern. If you don't parallelize, you would just sequentially reduce lists of ones (1,1,1,1...). Compare:

但是,如果您想并行化并使用 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

with the parallelized version (note the parmethod):

使用并行版本(注意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

you can use the MapReduce pattern in your case by defining the commonly used reduceByKeyfunction as follows:

您可以通过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)

you can debug it as before:

你可以像以前一样调试它:

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)

回答by Alexey Romanov

No, there is no built-in function which behaves like that. You can use mapValuesinstead of second mapto simplify it a bit, but there is no similar foldValues.

不,没有像那样的内置函数。您可以使用mapValues而不是 secondmap来简化它,但没有类似的foldValues.