找到集合中最常见/最常见的元素?

kor*_*dge 12 scala list

找到集合中最常见/最常见元素的最佳方法是什么?例如:

list = List(1, 3, 4, 4, 2)
list.mostCommon   // => 4        !! This is what I want !!
Run Code Online (Sandbox Code Playgroud)

嗯..什么人可以做的是做groupBy第一,然后map他们通过length,然后选择最大的一个.那么你会得到:

Map(1 -> List(1), 4 -> List(4, 4), 3 -> List(3), 2 -> List(2))
(...)
Map(1 -> 1, 4 -> 2, 3 -> 1, 2 -> 1)  // mapped by length. 4 -> 2  since there's two 4s
Run Code Online (Sandbox Code Playgroud)

最后,选择4映射到最高数字(2)的key ().(嵌套问题:最好的方法是什么?).但这对于这么简单的操作似乎有很多工作要做..?

是否有更好/更惯用的方法来做到这一点?

Tra*_*own 22

我不得不说:

list.groupBy(identity).mapValues(_.size).maxBy(_._2)._1
Run Code Online (Sandbox Code Playgroud)

要不就:

list.groupBy(identity).maxBy(_._2.size)._1
Run Code Online (Sandbox Code Playgroud)

对我来说真的不那么重要.

如果您担心只需要计数时为每个值建立列表的开销,您可以执行以下操作:

list.foldLeft(Map.empty[Int, Int].withDefaultValue(0)) {
  case (m, v) => m.updated(v, m(v) + 1)
}.maxBy(_._2)._1
Run Code Online (Sandbox Code Playgroud)

或者甚至在你去的时候跟踪最大值,以避免最后的额外遍历:

list.foldLeft(
  Map.empty[Int, Int].withDefaultValue(0), -1 -> Double.NegativeInfinity
) {
  case ((m, (maxV, maxCount)), v) =>
    val count = m(v) + 1
    if (count > maxCount) (m.updated(v, count), v -> count)
    else (m.updated(v, count), maxV -> maxCount)
}._2._1
Run Code Online (Sandbox Code Playgroud)

这显然比上面的单行程序更不易读取,所以我建议坚持使用它们,除非你能够显示(即通过基准测试,而不是猜测)它们是你应用程序的瓶颈.