2016-05-16 103 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}}'。儘管如此,必須有一個更清晰的方法。 –