1

我有一个案例类,例如:

 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
    }

所以问题是如何修改它最终会得到与 tpyereportsGroup2相同的结果reportsGroupBothMap[(String, String),List[agile.ReportData]]

4

2 回答 2

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)
  }
}

我们获取第一个组的每个组groupBygroupBy对其进行操作,然后将第一个键添加回。这些单独的组组中的每一个都被组合并作为一个映射返回。

于 2013-09-03T12:01:59.757 回答
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)
于 2013-09-03T12:23:51.510 回答