如何用Scala的groupBy和foldLeft实现列表分组求和函数
解决Scala中同时使用groupBy和foldLeft进行分组求和的问题
你当前的代码已经实现了分组求和的核心功能,但确实没用到foldLeft。我们可以调整分组后的处理逻辑,用foldLeft替代map.sum的方式,同时保留原有的业务逻辑。
修改后的函数实现
def sumIndex(listIn: List[String]): List[String] = { listIn .map(_.split(",")) // 将每个字符串拆分为数组 .groupBy(_(0)) // 按第一列(标题)分组 .map { case (title, items) => // 用foldLeft累加第三、第四列的数值,初始化累加器为(0,0) val (totalCol3, totalCol4) = items.foldLeft((0, 0)) { case ((sum3, sum4), arr) => (sum3 + arr(2).toInt, sum4 + arr(3).toInt) } // 取分组内第一个元素的第二列作为分类标签,拼接成目标格式字符串 s"$title,${items.head(1)},$totalCol3,$totalCol4" } .toList }
代码细节说明
- split与groupBy:和你的原代码逻辑一致,先把每个字符串拆分为数组,再按第一列的值完成分组。
- foldLeft的作用:这里用
foldLeft初始化了一个元组(0, 0)作为累加器,遍历分组内的每个数组元素时,将第三列、第四列的数值分别加到对应的累加项上,最终得到两列的总和。 - 结果拼接:延续你原代码的逻辑,取分组中第一个元素的第二列作为分类标签,用字符串插值拼接成目标格式。
测试验证
用你给出的输入测试这个函数:
val listInput1 = List( "itemA,CATs,2,4", "itemA,CATS,3,1", "itemB,CATQ,4,5", "itemB,CATQ,4,6", "itemC,CARC,5,10") val listOutput1 = sumIndex(listInput1) // 输出:List("itemA,CATs,5,5", "itemB,CATQ,8,11", "itemC,CARC,5,10")
注:你期望输出里itemA的第二列是CATS,但当前逻辑取的是分组第一个元素的CATs。如果需要统一格式(比如转大写或取分组内最后一个元素的第二列),可以把items.head(1)改成items.head(1).toUpperCase()或者items.last(1),按需调整即可。
内容的提问来源于stack exchange,提问作者scalacode
相关产品推荐
相关产品推荐

