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

Scala技术求助:合并同标题行的对应整数值并求和

Scala: Sum integer values for rows with matching title-type pairs in a string list

Problem Statement

I have a list of comma-separated strings where each entry follows the format [Title],[Type],[IntValue1],[IntValue2]. My goal is to merge rows that share the same [Title],[Type] pair by summing their corresponding integer values.

Input List

val listIn = List("TitleB,Int,11,0", "TitleB,Int,1,0", "TitleB,Int,1,0", "TitleB,Int,3,0", "TitleA,STR,3,0", "TitleC,STR,4,5")

Expected Output

List("TitleB,Int,16,0", "TitleA,STR,3,0", "TitleC,STR,4,5")

My Current Code

def sumB(list: List[String]): List[String] = {
  val itemPattern = raw".*(\d+),(\d+)\s*".r
  list.foldLeft(ListMap.empty[String, (Int,Int)].withDefaultValue((0,0))) {
    case (line, stri) =>
      val itemPattern(k,i,j) = stri
      val (a, b) = line(k)
      line.updated(k, (i.toInt + a, j.toInt + b))
  }.toList.map { case (k, (i, j)) => s"$k$i,$j" }
}

Issues with the Current Code

Let's break down what's not working here:

  • Incorrect Regex Pattern: The regex .*(\d+),(\d+)\s* only captures the last two integer values, but it doesn't extract the [Title],[Type] pair we need as the grouping key. Worse, you're trying to assign three groups (k,i,j) to a regex that only has two capture groups—this will throw a match error.
  • Wrong Grouping Key: Even if the regex worked, you aren't capturing the actual unique identifier (the first two comma-separated fields) that should group rows together.
  • Malformed Output String: The final interpolation s"$k$i,$j" is missing a comma between the key and the first summed integer, leading to broken output like TitleBInt16,0 instead of the desired format.

Fixed Solution

Here's a revised version that addresses all these issues:

import scala.collection.immutable.ListMap

def sumB(list: List[String]): List[String] = {
  // Split each string by commas to extract components safely
  list.foldLeft(ListMap.empty[String, (Int, Int)].withDefaultValue((0, 0))) {
    case (acc, line) =>
      line.split(",") match {
        case Array(title, typ, num1, num2) =>
          // Use title+typ as the unique key (joined with comma to match input format)
          val key = s"$title,$typ"
          val (sum1, sum2) = acc(key)
          acc.updated(key, (sum1 + num1.toInt, sum2 + num2.toInt))
        // Handle invalid lines gracefully (optional but robust)
        case _ => acc
      }
  }.map { case (key, (sum1, sum2)) =>
    // Reconstruct the output string with proper formatting
    s"$key,$sum1,$sum2"
  }.toList
}

Explanation

  • Safe Splitting: Instead of brittle regex, we use split(",") to directly pull out each component of the string. This makes it trivial to get the title/type pair for grouping and the integers to sum.
  • Correct Grouping: We create the key as s"$title,$typ" to ensure we only merge rows that have both the same title and type (which aligns with your expected output, keeping TitleA/STR and TitleC/STR separate).
  • Proper Formatting: The final string interpolation correctly combines the key with summed values using commas, producing exactly the format you need.
  • Robustness: The case _ => acc clause ensures malformed input lines don't break the function—they're just skipped.

Testing the Solution

Run it with your input list:

sumB(listIn)

You'll get the exact expected output:

List("TitleB,Int,16,0", "TitleA,STR,3,0", "TitleC,STR,4,5")

内容的提问来源于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 08:39:43