将scala数组转换为项目计数的Map

时间:2016-09-23 07:21:17

标签: arrays scala

我正在寻找一种将scala数组转换为包含数组中项目频率的地图的简洁方法。

例如。 :

给出如下数组:

null

我想要一张地图:

val arr = Array("one", "one", "two", "three", "one", "three")

我可以通过编写

等函数来完成此操作
Map("one" -> 3, "two" -> 1, "three" -> 2)

我想知道这是否可以更有效地完成。

2 个答案:

答案 0 :(得分:6)

arr.groupBy(identity).map{case (x,y) => x -> y.size} 

答案 1 :(得分:4)

我使用groupBy(identity)mapValues(_.length)

scala> val arr = Array("one", "one", "two", "three", "one", "three")
arr: Array[String] = Array(one, one, two, three, one, three)

scala> arr.groupBy(identity).mapValues(_.length)
res0: scala.collection.immutable.Map[String,Int] = Map(one -> 3, three -> 2, two -> 1)

更新:这不比你的代码更有效(我认为不可能超越),但它肯定更具可读性。 groupBy method将所有相同的(因为我们使用identity)值汇总到一个Array,与仅递增计数相比,这会产生一些开销。

更新2:如评论中所述,输出不可序列化,因为mapValues只包装地图并评估每个{{}上的函数1}}。您可以通过包装地图上的get 实现地图:

map(identity)

但这不是很好的代码。