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

Scala合并Case Class列表生成差值对比类及groupBy顺序疑问

Scala 合并两个ScoreOutput列表生成ScoreComparison的最优方案

最优实现方式

根据你的需求,分两种场景给出最优实现:

场景1:两个列表的ID完全匹配且顺序一致

如果能确保originalScores和currentScores中的元素按ID一一对应且顺序相同,直接使用zip方法是最高效的:

// 先修正原代码的ID类型(case class定义id为String,字面量需加引号)
case class ScoreOutput(id: String, runDate: String, score: Double)
val originalScores: List[ScoreOutput] = List(
    ScoreOutput("1", "09-21", 5.0), 
    ScoreOutput("2", "09-21", 3.0),
    ScoreOutput("3", "09-21", 2.0)
)

val currentScores: List[ScoreOutput] = List(
    ScoreOutput("1", "10-01", 20.0), 
    ScoreOutput("2", "10-01", 1.0),
    ScoreOutput("3", "10-01", 18.0)
)

case class ScoreComparison(name: String, originalDate: String, currentDate: String, scoreChange: Double)

val scoreDiff: List[ScoreComparison] = originalScores.zip(currentScores).map {
    case (orig, curr) => 
        ScoreComparison(
            orig.id, 
            orig.runDate, 
            curr.runDate, 
            curr.score - orig.score
        )
}

场景2:列表可能存在ID缺失或顺序不一致

如果无法保证ID的匹配性和顺序,将列表转为以ID为键的Map再合并更可靠:

// 转换为Map便于按ID查找
val originalMap = originalScores.map(s => s.id -> s).toMap
val currentMap = currentScores.map(s => s.id -> s).toMap

// 仅保留两个列表都存在的ID生成结果
val scoreDiff: List[ScoreComparison] = originalMap.keys.intersect(currentMap.keys).toList.map { id =>
    val orig = originalMap(id)
    val curr = currentMap(id)
    ScoreComparison(id, orig.runDate, curr.runDate, curr.score - orig.score)
}

// 若需要包含仅在单个列表中存在的ID,可扩展为:
// val allIds = originalMap.keys ++ currentMap.keys
// allIds.map { id =>
//     val orig = originalMap.getOrElse(id, ScoreOutput(id, "", 0.0))
//     val curr = currentMap.getOrElse(id, ScoreOutput(id, "", 0.0))
//     ScoreComparison(id, orig.runDate, curr.runDate, curr.score - orig.score)
// }.toList

关于groupBy的顺序疑问

当你通过originalScores ++ currentScores合并列表后执行groupBy(_.id),无法保证组内元素的顺序:

  • Scala的groupBy默认返回普通HashMap,其遍历顺序是不确定的(Scala 2.13之前完全无序,2.13之后虽有有序Map实现,但groupBy仍默认返回无序HashMap)。
  • 即使合并后的列表是先原列表元素、后当前列表元素,groupBy生成的List中元素的顺序也依赖于Map的内部实现,不能保证第一个元素一定来自originalScores。因此这种方式不可靠,不推荐用来区分两个来源的元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:35:29