我想将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
}
是否有一个库方法可以为我提供此结果(理想情况下,可以很好地处理并行集合)?
答案 0 :(得分: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
}
}
不一定是最快的解决方案,但简洁明了:)
答案 1 :(得分:1)
t.foldLeft(Map.empty[Int, Int].withDefaultValue(0)) { (acc, i) => acc.updated(i, acc(i) + 1) }
答案 2 :(得分:0)
我会考虑使用直方图函数对遍历进行遍历。创建一个隐式类,将“toHistogram [T]”添加到遍历。我不认为标准库中存在功能。