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

Scala列表按标题分组求和后顺序错乱,如何修复?

解决Scala分组求和时保留原列表顺序的问题

你的问题核心在于groupBy返回的是无序的Map(Scala 2中默认是HashMap,Scala 3的Map虽改为有序,但为了兼容多版本,最好显式维护顺序),转成List后元素顺序会偏离原列表中标题首次出现的顺序。下面给你两种修复方案,同时还解决了原输入中存在空格导致toInt报错的潜在问题:

方案一:使用LinkedHashMap维护插入顺序(可变集合)

通过LinkedHashMap记录标题的首次出现顺序,在分组求和的同时保留原列表的顺序:

import scala.collection.mutable.LinkedHashMap

def sumByTitle(listInput: List[String]): List[String] = {
  // 先处理每个元素的空格问题,避免toInt报错
  val splitItems = listInput.map(_.split(",").map(_.trim))
  
  // 用LinkedHashMap维护标题的出现顺序,同时累加求和
  val grouped = splitItems.foldLeft(LinkedHashMap[String, (String, Int, Int)]()) { 
    case (acc, arr) =>
      val title = arr(0)
      val category = arr(1)
      val num1 = arr(2).toInt
      val num2 = arr(3).toInt
      
      acc.get(title) match {
        // 如果标题已存在,累加数值
        case Some((cat, sum1, sum2)) =>
          acc.update(title, (cat, sum1 + num1, sum2 + num2))
        // 如果标题是第一次出现,初始化条目
        case None =>
          acc.put(title, (category, num1, num2))
      }
      acc
  }
  
  // 按LinkedHashMap的顺序转为结果列表
  grouped.map { case (title, (cat, sum1, sum2)) =>
    s"$title,$cat,$sum1,$sum2"
  }.toList
}

方案二:先提取标题顺序再生成结果(不可变集合)

如果你偏好不可变集合,可以先提取原列表中标题的去重顺序(保留首次出现的顺序),再按这个顺序从分组结果中生成最终列表:

def sumByTitle(listInput: List[String]): List[String] = {
  // 处理空格并拆分每个元素
  val splitItems = listInput.map(_.split(",").map(_.trim))
  
  // 获取原列表中标题的首次出现顺序(去重)
  val titleOrder = splitItems.map(_(0)).distinct
  
  // 按标题分组
  val grouped = splitItems.groupBy(_(0))
  
  // 按照原顺序遍历标题,生成求和结果
  titleOrder.map { title =>
    val features = grouped(title)
    val category = features.head(1)
    val sumNum1 = features.map(_(2).toInt).sum
    val sumNum2 = features.map(_(3).toInt).sum
    s"$title,$category,$sumNum1,$sumNum2"
  }
}

测试验证

用你的输入示例测试:

  • 对于listInput1,两个方案都会返回List("itemA,CATA,5,5", "itemB,CATB,8,11"),顺序和原列表完全一致
  • 对于listInput2,因为每个标题只出现一次,结果顺序完全匹配原输入

另外,原函数未处理输入字符串的空格(比如"itemA,CATA,2,4 "末尾的空格),直接toInt会抛出NumberFormatException,上面的方案都通过trim()处理了这个问题,让代码更健壮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:44:50