[英]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
map
為a
而不必模式-全部匹配。
另一方面,在您的列表中收集特定類型的數據。 因為我們希望能夠基於類型而不是數據進行收集。 最好對您的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.