Scala中的条件组

时间:2013-09-03 11:33:08

标签: scala

我有一个案例类:

 case class ReportData(
    building: Option[String] = None,
    serial: Option[String] = None,
    `type`: Option[String] = None,
    model: Option[String] = None,
    machine: Option[String] = None)

和其他领域。

我有这些对象的列表,例如:

val reports = List(report1, report2, report3, report11, report12)

请求是对这些类的特定字段执行一些特定的复杂操作,例如,这些列表仅按接收的字段列出:groupFields="building,serial"

这是一个精细组的例子:

val reportsGroupBoth = reports.groupBy(p => (p.building.getOrElse(""), p.serial.getOrElse("")))

但是我希望根据收到的字段使其成为条件,所以我想的唯一方法就是为每个字段分隔分组(我稍后会添加if condition现在我只想获得与以上group by如果我将它们分开,则结果为:Map[(String, String),List[agile.ReportData]]

所以我试过了:

// group by building (if building is defined in groupFields list)
val reportsGroup1 = reports.groupBy(p => p.building)

这很好,但这个错了:

// group by building and serial (if building and serial are in groupFields list)
val reportsGroup2 = reportsGroup1 map {
        case (key, value) => (key, value.groupBy(v => v.serial).keys) -> value.groupBy(v => v.serial).values
    }

所以问题是如何修改reportsGroup2,最终它将与tpye reportsGroupBoth的{​​{1}}具有相同的结果

2 个答案:

答案 0 :(得分:2)

这将有效:

val reportsGroup1 = reports.groupBy(p => p.building.getOrElse(""))

val reportsGroup2 = reportsGroup1 flatMap {
  case (key, value) => value.groupBy(v => v.serial.getOrElse("")).map {
    case (key2, value) => ((key, key2), value)
  }
}

我们获取第一个groupBy的每个组并对其执行groupBy,然后重新添加第一个键。将这些单独的组中的每个组合并作为一个映射返回

答案 1 :(得分:1)

如果您只想按两个非空字段分组

reports.groupBy(r => (r.building, r.serial)).flatMap({
   case ((Some(b),Some(s)),v) => Some((b,s) -> v)
   case _ => None
})

如果你想按照你的建议分组:

val reportsGroup2 = reportsGroup1.map({
   case (key, value) => value.groupBy(v => (key, v.serial))
}).flatten.flatMap({
   case ((Some(b),Some(s)),v) => Some((b,s) -> v)
   case _ => None
}).toMap

你会得到相同的

也许您想要设置一些分组策略,例如:

val buildingSerialPolicy = 
   Seq[ReportGroup => Option[String](_.building, _.serial)

然后只需拨打所需的政策:

val removeEmptyKeys = ...

report.groupBy(r => 
   buildingSerialPolicy.map(_.apply(r))).flatMap(removeEmptyKeys)