Scala foldLeft map和termCount文件

时间:2014-01-30 20:07:39

标签: scala functional-programming

我有一份文件清单,我希望在所有文件中找到(term -> termCount)对。我是这样做的:

object termCount extends App {

  val docs = List(
    List("A", "B", "C", "C"),
    List("A", "D"),
    List("B", "B", "C"))

  val countsMap = docs.flatMap { ts =>
    val m = ts.map((_, 1)).groupBy(_._1)
    m.map { e => e._1 -> e._2.foldLeft(0)(_ + _._2) }
  }.groupBy(_._1)
    .map { e => e._1 -> e._2.foldLeft(0)(_ + _._2) }

  println(countsMap)

}

输出:

Map(D -> 1, A -> 2, C -> 3, B -> 3)

要将其分解为操作,我所做的是:

  • 生成(term, 1)

    的元组
    val m = ts.map((_, 1)).groupBy(_._1)
    
  • 计算文档本地termCount e => e._1 -> e._2.foldLeft(0)(_ + _._2)

  • 生成Map文档本地(term -> termCount)条目

  • 在所有文档中将此地图展平为元组(term, termCount)

  • 还会再次执行foldLeft以获取全球期限

我的问题是,如何让这段代码更简洁?

1 个答案:

答案 0 :(得分:2)

这非常简洁:

scala> docs.flatten.groupBy(identity).map { case (k,vs) => (k,vs.size)}
res0: scala.collection.immutable.Map[String,Int] = Map(D -> 1, A -> 2, C -> 3, B -> 3)

有助于原始代码的一件事是你在两个不同的级别执行相同的foldLeft操作:首先在每个子列表上,然后在整个事件上。您可以将集合flatten改为一个大列表,这样您只需要执行一次:

顺便说一下:这是一个foldLeft方式:

docs.flatten.foldLeft(Map.empty[String,Int]){ case (z,x) => z.updated(x, z.getOrElse(x,0) + 1) }