Scala 什么';将TraversableOnce[T]转换为类似多集或直方图的映射[T,Int]的最干净的方法是什么?

Scala 什么';将TraversableOnce[T]转换为类似多集或直方图的映射[T,Int]的最干净的方法是什么?,scala,multiset,Scala,Multiset,我想把一个可遍历的[T]转换成一个带有计数的Map[T,Int]直方图。我希望结果是一个不可变的映射,它与我通过执行以下操作得到的结果相匹配: traversable.groupBy(_).mapValues(_.length) 但这看起来在空间或时间上都不高效……因为groupBy维护了对可遍历对象中每个元素的引用,所以在具有少量唯一键的大型可遍历对象上的性能很差。我真的想要更像这样的东西: def histogram[T](ts : Traversable[T]) : Map[T, Int

我想把一个可遍历的[T]转换成一个带有计数的Map[T,Int]直方图。我希望结果是一个不可变的映射,它与我通过执行以下操作得到的结果相匹配:

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
}

是否有一个库方法给了我这个结果(并且理想地,它与并行集合一起工作得很好)?

我会考虑用直方图函数来处理PimrPrimvices。创建一个隐式类,将“toHistogram[T]”添加到可遍历项中。我认为标准库中没有这种功能。

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

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

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

acc.updated(i,acc(i)+1)}对不起,我的版本不是通用的,但你可以很容易地将其设置为默认版本,并且为了简洁和清晰,你的版本与任何版本一样好。