问题描述
我有几个案例类,例如:
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
中收集 TypeX。我正在做类似的事情:
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,"abc")) -> 1,"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
,那么您只需map
您的collectedList
到a
,而不必对所有内容进行模式匹配。
另一方面,在您的列表中收集特定类型的数据。
因为我们希望能够根据类型而不是数据进行收集。
你最好在你的 collect
上做一个 collectedList
并对你正在追逐的类型进行部分匹配 ala
val successList = collectedList.collect { case i: SuccessCount => i }
val warningList = collectedList.collect { case i: WarningCount => i }
您甚至可以通过为自己创建一个辅助函数来概括这一点:
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)