2016-05-16 66 views
0

我有2例类:斯卡拉地图收集案例映射类()

case class OutlierPortal(portal: String, timeData: Seq[OutlierPortalTimeSeriesData]) 

case class OutlierPortalTimeSeriesData(period: Timestamp, totalAmount: Double, isOutlier: Int) 

或分别为Seq[OutlierPortal]

我要执行类似到Scala Macros: Making a Map out of fields of a class in Scala,但我想映射一个(嵌套)case-classes的序列到Seq[Map[String, Any]]

不过,scala新手我恐怕有点建议。有没有一种“简单”的方法来映射这个序列Seq[OutlierPortal]Seq[Map[String, Any]]

或者你会推荐开始使用宏,即使在scala初学者?对于我来说,单向转换(case-class - > map)就足够了。

+0

要清楚,你正在寻求避免硬编码的字符串? –

+0

灵活的键会很好,但不是强制性的 –

+0

你想''任何''类型的值'包含字段值? –

回答

4

如果您希望避免花哨的技巧,并且您没有太多的总课程来编写它,您可以编写自己创建地图的方法。我建议在您的案例类中添加名为toMap的方法。 OutlierPortalTimeSeriesData的很简单,如果你使用Map()构造:

case class OutlierPortalTimeSeriesData(period: Timestamp, totalAmount: Double, isOutlier: Int) { 
    def toMap: Map[String, Any] = Map(
    "period" -> period, 
    "totalAmount" -> totalAmount, 
    "isOutlier" -> isOutlier) 
} 

我想有一些重复出现,但至少,如果你有一个理由去改变的字符串值,而不是变量名,您可以灵活要做到这一点。

要采取的一些序列,你可以拨打toMap,并把它变成一个Seq[Map[String, Any]],只需使用map

mySeq.map { _.toMap } 

我们可以利用这个既写OutlierPortaltoMap

case class OutlierPortal(portal: String, timeData: Seq[OutlierPortalTimeSeriesData]) { 
    def toMap: Map[String, Any] = Map(
    "portal" -> portal, 
    "timeData" -> timeData.map { _.toMap }) 
} 

然后再次将Seq[OutlierPortal]转换为Seq[Map[String, Any]]

取决于你如何使用这些对象和方法,你可能希望定义使用这种方法区分阶级的性状,并有你的case类扩展它:

trait HasToMap { def toMap: Map[String, Any] } 
case class Blah(/* ... */) extends HasToMap { 
    def toMap: /* ... */ } 
} 

这将让你拿一个值,你知道你可以转换为Map[String, Any](或他们的序列等)在一个方法,否则不关心它是哪种特定的类型。

+0

现在实现这个解决方案我得到以下错误:'def mapOutliersForJobserver(异常值:未来[Seq [OutlierPortal]]):未来[Seq [Map [String,Any]]] = { outliers.map(_.toMap) }错误:未来[Map [Nothing,Nothing]]不符合Future类型[Seq [Map [String,Any]]]'这里有什么问题?它是Seq [T]? –

+0

@geoHeil你正在试图像'Seq [T]'一样对待'Future [Seq [T]]'。不过,它们与Seq [Seq [T]]是不同的。 –

+0

@geoHeil所以例如,你可以使用两个嵌套的调用来映射''{outliers.map {_.map {_.toMap}}'。尽管如此,必须有一个更清晰的方法。 –