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
Scala - reduce function
提问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.

