我正在尋找將我的案例串列物件轉換為地圖。這
輸入類看起來像這樣
case class MyData(
source: String,
dataMap: Map[String, String]
)
轉換后的結果類
case class LiverampMappingV2(
dataMapping: Map[String, Map[String, Seq[String]]]
)
比如下面的輸入資料 -->
val data = List(
new myData("abc.com", Map("key1" -> "value1", "key2" -> "value2")),
new myData("abc.com", Map("key1" -> "value11", "key3" -> "value3")),
new myData("pqr.com", Map("key1" -> "value111", "key3" -> "value33"))
)
將按如下方式組裝
Map(
key1 -> Map("abc.com" -> List("value1", "value11"), "pqr.com" -> List("value111")),
key2 -> Map("abc.com" -> List("value2")),
key3 -> Map("abc.com" -> List("value13"), "pqr.com" -> List("value33"))
)
我嘗試了幾個使用組合的選項groupBy
,groupMap
然后是flatten
scala和函式式編程的新手,我無法達到最終的解決方案。
任何幫助或指導表示贊賞。
uj5u.com熱心網友回復:
如果您的范圍內沒有貓,我也可以推薦另一種方法:D 盡管這非常冗長且有點復雜。那是因為您需要在每次迭代中折疊您的第一個原始“資料”。但我會嘗試解釋:
type MP = Map[String, List[String]]
// just for shortening the code, you can put a better name on it
data.foldLeft[Map[String, MP]](Map.empty)(
(agg, newData) => {
val source = newData.source
newData.dataMap.foldLeft(agg) {
case (updatingAggregator, (key, value)) =>
updatingAggregator.updatedWith(key) {
case Some(existingMap) =>
Some(existingMap.updatedWith(source) {
case Some(existingList) => Some(value :: existingList)
case None => Some(value :: Nil)
})
case None =>
Some(Map(source -> (value :: Nil)))
}
}
}
)
基本上我們在這里做的是折疊data
,零值empty Map of String to MP
(這是我們從演算法和折疊中想要的結果型別)。在每次迭代中,您都有源 ( val source = ...
)。而且您還有一個 dataMap,您需要再次折疊它 (:D),并agg
使用給定的源、鍵和值更新其中先前創建的值。現在在 updatedWith 方法中,您基本上是在 updatesAggregatorsource
內部查找,如果它已經有了,您只需將值添加到前面,如果沒有,您只需創建它。如果描述不夠清楚,請告訴我。
uj5u.com熱心網友回復:
如果您的范圍內有貓Monoid
,這非常簡單,因為您可以利用Map
import cats.syntax.all._
def groupByNested(data: List[MyData]): Map[String, Map[String, List[String]]] =
data.foldMap {
case MyData(source, dataMap) =>
dataMap.map {
case (key, value) =>
key -> Map(source -> (value :: Nil))
}
}
我對函式名稱并不完全滿意。
你可以看到它在這里運行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/478728.html