scala - 将一对列表减少到键映射及其聚合计数的惯用方法?

标签 scala

我正在尝试重新创建 Hadoop 的 word count在一个简单的 Scala 程序中映射/减少逻辑以供学习

这是我到目前为止

val words1 = "Hello World Bye World"      
val words2 = "Hello Hadoop Goodbye Hadoop"

val input = List(words1,words2)           
val mapped = input.flatMap(line=>line.split(" ").map(word=>word->1))
    //> mapped  : List[(String, Int)] = List((Hello,1), (World,1), (Bye,1), 
    //                                       (World,1), (Hello,1), (Hadoop,1), 
    //                                       (Goodbye,1), (Hadoop,1))

mapped.foldLeft(Map[String,Int]())((sofar,item)=>{
    if(sofar.contains(item._1)){
        sofar.updated(item._1, item._2 + sofar(item._1))
    }else{
        sofar + item
    }
})                              
    //>Map(Goodbye -> 1, Hello -> 2, Bye -> 1, Hadoop -> 2, World -> 2)

这似乎有效,但我确信有一种更惯用的方法来处理减少部分(foldLeft)

我正在考虑使用 multimap,但我觉得 Scala 有一种方法可以轻松做到这一点

在那儿?例如添加到 map 的方法,如果键存在,而不是替换它,将值添加到现有值 .我确定我在某处看到过这个问题,但找不到它,也找不到答案。

我知道 groupBy是可能在现实世界中做到这一点的方法,但我正在尝试尽可能接近上面链接中的原始映射/减少逻辑来实现它。

最佳答案

您可以使用 Scalaz's |+|运营商因为 MapsSemigroup 的一部分类型类:
|+|运算符是 Monoid mappend函数(Monoid 是任何可以“添加”在一起的“东西”。很多东西可以像这样添加在一起:字符串、整数、 map 、列表、选项等。一个例子:

scala> import scalaz._
import scalaz._

scala> import Scalaz._
import Scalaz._

scala> val map1 = Map(1 -> 3 , 2 -> 4)
map1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 4)

scala> val map2 = Map(1 -> 1, 3 -> 6)
map2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1, 3 -> 6)

scala> map1 |+| map2
res2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 4, 3 -> 6, 2 -> 4)

所以在你的情况下,而不是创建一个 List[(String,Int)] , 创建 List[Map[String,Int]] ,然后将它们相加:
val mapped = input.flatMap(_.split(" ").map(word => Map(word -> 1)))
mapped.suml

关于scala - 将一对列表减少到键映射及其聚合计数的惯用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13868465/

相关文章:

带有 postfixOps 的 Scala 映射

scala - 为什么我不能在 Scala 中打印调试消息?

scala - 为什么 Scala 类型与预期的 Int 不匹配?

arrays - 减去数组中指定索引处的元素

scala - 在控制台的 Scala 应用程序中排队

scala - 来自 SBT 的多个 docker 镜像

scala - 如何将不做任何处理的处理程序设置为按名称参数?

scala - Spark : FlatMap and CountVectorizer pipeline

scala - EC2 上的 Spark Streaming : Exception in thread "main" java. lang.ExceptionInInitializerError

scala - 从 Array 中随机选择 n 个元素