You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala如何按元素出现次数分组?是否有对应内置函数?

在Scala中按元素出现次数分组的实现方法

当然有办法实现!Scala的标准集合库虽然没有直接提供一个一步到位的函数,但通过几个常用方法的组合,就能轻松得到你想要的结果。咱们结合你的例子一步步来:

首先,先看你的输入列表:

val x = List("c", "b", "b", "c", "a", "d", "c")

步骤1:分组相同元素

用groupBy(identity)可以把列表中相同的元素归为一组,返回一个Map,键是元素本身,值是该元素组成的子列表:

x.groupBy(identity)
// 结果:Map(c -> List(c, c, c), b -> List(b, b), a -> List(a), d -> List(d))

步骤2:统计每组元素的数量

接着用mapValues(_.size)把每个子列表转换成它的长度(也就是元素的出现次数),这样就得到了元素和对应次数的映射:

x.groupBy(identity).mapValues(_.size)
// 结果:Map(c -> 3, b -> 2, a -> 1, d -> 1)

步骤3:转换成列表并排序

把上面的Map转换成列表,再按次数降序排序(这样次数多的元素排在前面),最后调换元组的顺序让次数在前:

val result = x.groupBy(identity)
              .mapValues(_.size)
              .toList
              .sortBy(-_._2) // 用负号实现降序
              .map { case (elem, count) => (count, elem) }

// 最终结果:List((3, "c"), (2, "b"), (1, "a"), (1, "d"))

额外优化:保持元素首次出现的顺序

如果你的需求里,次数相同的元素需要按照它们在原列表中首次出现的顺序排列(就像你的示例里a在d前面),可以先记录每个元素第一次出现的索引,再结合排序:

// 先记录每个元素首次出现的位置
val firstOccurrence = x.zipWithIndex.foldLeft(Map[String, Int]()) {
  case (acc, (elem, idx)) => acc.getOrElseUpdate(elem, idx)
}

val orderedResult = x.groupBy(identity)
                     .mapValues(_.size)
                     .toList
                     .sortBy { case (elem, count) => (-count, firstOccurrence(elem)) }
                     .map { case (e, c) => (c, e) }

这样处理后,次数相同的元素就会严格按照它们第一次出现的顺序排列啦。

总的来说,Scala的集合操作非常灵活,通过groupBy、mapValues和排序方法的组合,完全能满足你的需求~

内容的提问来源于stack exchange,提问作者Dadou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:30:54