簡體   English   中英

Scala:模式匹配案例類的圈復雜度太高

[英]Scala: cyclomatic complexity too high for pattern matching case classes

我有一些案例類,例如:

case class TypeX(a: Int, b: Int, c: String)
sealed trait metrictypes
object metrictypes {
  case class SuccessCount(a: TypeX) extends metrictypes
  case class FailureCount(a: TypeX) extends metrictypes
  case class WarningCount(a: TypeX) extends metrictypes
     .....

我有 10 個這樣的案例課程 ^

我有一些功能可以生成 List[metrictypes] 類型的列表collectedList 例如:

List(SuccessCount(TypeX(111, 222, "abc")), WarningCount(TypeX(999, 777, "zzz")))

我需要計算 metrictype 並在列表finalList 我正在做類似的事情:

  val finalList = new ListBuffer[TypeX]()
  val result = collectedList {x =>
    x match {
      case SuccessCount(a)  => incrementSuccessCount(); finalList += a
      case FailureCount(a)  => incrementFailureCount(); finalList += a
      .... (10 times)
      case _ => println("Unknown!")

    }
  }

我知道這不是最干凈或最有效的方法,它也會導致高圈復雜度。 我該如何改進呢?

我還嘗試通過執行以下操作根據度量類型對它們進行分組:

  val groupedList = collectedList.groupBy(i => i).mapValues(_.map(_ => 1).reduce(_ + _))

這導致

Map(SuccessCount(TypeX(111, 222, "abc")) -> 1, WarningCount(TypeX(999, 777, "zzz")) -> 1))

仍然無法弄清楚如何獲取 metrictypes 的出現次數並僅在列表中收集 TypeX。

如果您將設計更改為以下內容會怎樣:

final case class TypeX(a: Int, b: Int, c: String)

sealed trait MetricType
object MetricType {
  final case object Success extends MetricType
  final case object Failure extends MetricType
  final case object Warning extends MetricType
}

final case class MetricCount(tpe: MetricType, a: TypeX)

然后你可以像這樣使用它:

def processCounts(data: List[MetricCount]): (List[TypeX], Map[MetricType, Int]) = {
  val finalList = data.map(_.a)
  val countsByMetricType = data.groupMapReduce(_.tpe)(_ => 1)(_ + _)
  
  finalList -> countsByMetricType
}

這有幫助嗎?

如果您的案例類中的所有數據實際上都具有TypeX的數據,那么您應該使用metrictype特征來概括您的所有案例類都具有a: TypeX那么您可以將您的collectedList mapa而不必模式-全部匹配。

另一方面,在您的列表中收集特定類型的數據。 因為我們希望能夠基於類型而不是數據進行收集。 最好對您的collectedList collect部分匹配您正在尋找ala的類型

val successList = collectedList.collect { case i: SuccessCount => i }
val warningList = collectedList.collect { case i: WarningCount => i }

您甚至可以通過為自己創建一個助手 function 來概括這一點:

def collectByType[B <: A](collectedList: List[A]): List[B] =
  collectedList.collect{ case i: B => i }
val successList = collectByType[SuccessCount](collectedList)
val warningList = collectByType[WarningCount](collectedList)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM