2

我想将 Traversable[T] 转换为带有计数的 Map[T, Int] 直方图。我希望结果是一个不可变的 Map ,它与我会得到的结果相匹配:

traversable.groupBy(_).mapValues(_.length)

但看起来这在空间或时间上效率不高......因为groupBy维护对可遍历中的每个元素的引用,这在具有少量唯一键的大型可遍历上表现不佳。我真的想要更像这样的东西:

def histogram[T](ts : Traversable[T]) : Map[T, Int] = {
  val map = new collection.mutable.HashMap[T, Int].withDefaultValue(0)
  ts.foreach { map(_) += 1 }
  map.toMap
}

有没有一种库方法可以给我这个结果(理想情况下,可以很好地与并行集合一起使用)?

4

3 回答 3

1

t.foldLeft(Map.empty[Int, Int].withDefaultValue(0)) { (acc, i) => acc.updated(i, acc(i) + 1) }

于 2013-03-28T20:51:56.023 回答
1

这是我的扩展,与您的建议非常相似:

implicit final class RichIterable[A](val it: TraversableOnce[A]) extends AnyVal {
  def histogram: Map[A, Int] = {
    var res = Map.empty[A, Int] withDefaultValue 0
    it.foreach { elem =>
      res += elem -> (res(elem) + 1)
    }
    res
  }
}

不一定是最快的解决方案,但简洁:)

于 2013-03-28T20:18:47.927 回答
0

我会考虑用你的直方图函数来拉扯可遍历的东西。创建一个将“toHistogram[T]”添加到可遍历的隐式类。我认为标准库中没有该功能。

于 2013-03-28T20:16:39.340 回答