Scala中如何从继承trait的样例类集合中提取字段值
解决方案
首先先修正你代码里的一个小错误:Template("cde")是无效的,因为Template是trait不能直接实例化,得改成TemplateA("cde")才行。
接下来针对你要收集特定字段并分组统计的需求,给你两种实用的实现方式:
方式一:用collect+groupBy快速处理
这种方式逻辑清晰,先过滤出目标类型的实例、提取字段,再分组统计次数:
sealed trait Template object Template { case class TemplateA(field: String) extends Template case class TemplateB extends Template } object Runner { def main(args: String*) { val list = List(Template.TemplateA("abc"), Template.TemplateB, Template.TemplateA("cde")) // 过滤TemplateA实例、提取字段 → 分组 → 格式化输出 val result = list.collect { case Template.TemplateA(field) => field }.groupBy(identity) .map { case (field, items) => s"$field;${items.size}" } // 打印结果 result.foreach(println) } }
逻辑说明:
collect配合模式匹配,只保留TemplateA实例并提取它的field字段,得到纯字段值的列表groupBy(identity)按字段值分组,把相同字段的实例归到一起- 最后把分组后的键值对格式化成
"字段;次数"的字符串
方式二:用foldLeft直接计数(更高效)
如果不想生成中间列表,可以用foldLeft直接遍历计数,减少内存开销:
val result = list.foldLeft(Map.empty[String, Int]) { (countMap, item) => item match { case Template.TemplateA(field) => countMap.updated(field, countMap.getOrElse(field, 0) + 1) case _ => countMap } }.map { case (field, count) => s"$field;$count" }
逻辑说明:
- 初始化一个空的计数字典,遍历列表时遇到
TemplateA就更新对应字段的计数,其他类型直接跳过 - 最后同样格式化为需要的字符串格式
两种方式运行后都会输出:
abc;1 cde;1
内容的提问来源于stack exchange,提问作者glaz666
相关产品推荐
相关产品推荐

