【问题标题】:Scala foldLeft map and termCount of documentsScala foldLeft 地图和 termCount 文档
【发布时间】:2014-01-30 20:07:38
【问题描述】:

我有一个文档列表,我想在所有文档中找到 (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)

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

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

  • 还再次执行foldLeft 以获取全局术语计数

我的问题是,我怎样才能使这段代码更简洁?

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    这很简洁:

    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) }
    

    【讨论】:

      猜你喜欢
      • 2011-05-09
      • 1970-01-01
      • 2019-02-10
      • 2012-03-25
      • 1970-01-01
      • 1970-01-01
      • 2011-12-07
      • 2017-11-04
      • 1970-01-01
      相关资源
      最近更新 更多