从地图列表列表中提取地图值[Map [String,Any]]?

时间:2017-10-16 11:53:47

标签: scala scala-collections

如何进行模式匹配以从列表中包含的地图中提取值?

所以我的数据类型为List[Map[String,Any]],看起来像是:

List(Map(sequence -> 192, id -> 8697413670252052, type -> List(AimLowEvent, DiscreteEvent), time -> 527638582195))
List(Map(duration -> 143858743, id -> 8702168014834892, sequence -> 195, sessionId -> 8697344444103393, time -> 527780267698, type -> List(SessionCanceled, SessionEnded)), Map(trackingInfo -> Map(trackId -> 14170286, location -> Browse, listId -> cd7c2c7a-00f6-4035-867f-d1dd7d89972d_6625365X3XX1505943605585, videoId -> 80000778, rank -> 0, row -> 0, requestId -> ac12f4e1-5644-46af-87d1-ec3b92ce4896-4071171), id -> 8697344444103393, sequence -> 89, time -> 527636408955, type -> List(Play, Action, Session)), 1)
List(Map(duration -> 142862569, id -> 8702168403395215, sequence -> 201, sessionId -> 8697374208897843, time -> 527780267698, type -> List(SessionCanceled, SessionEnded)), Map(trackingInfo -> Map(trackId -> 14170286, location -> Browse, listId -> cd7c2c7a-00f6-4035-867f-d1dd7d89972d_6625365X3XX1505943605585, videoId -> 80000778, rank -> 0, row -> 0, requestId -> ac12f4e1-5644-46af-87d1-ec3b92ce4896-4071171), id -> 8697374208897843, sequence -> 136, time -> 527637405129, type -> List(Play, Action, Session)), 1)

首先,我只想保留包含Map(trackingInfo -> ..的记录,因为对我来说重要的字段在这些记录中,例如trackId。但是在那些相同的记录中,我还需要外部字段,例如sequence

我已经厌倦了将列表展平为Map by,所以我可以匹配地图:

myList.flatten.toMap

但是它会返回java.lang.ClassCastException: scala.collection.immutable.Map$Map4 cannot be cast to scala.Tuple2错误。

感谢任何帮助

2 个答案:

答案 0 :(得分:0)

对于你想要达到的目标,我相信filter会做:

// taken from your example and simplified
val list =
  List(
    Map("duration" -> 142862569L, "id" -> 8702168403395215L, "sequence" -> 201, "sessionId" -> 8697374208897843L, "time" -> 527780267698L, "type" -> List("SessionCanceled", "SessionEnded")),
    Map("trackingInfo" -> Map("trackId" -> 14170286L, "location" -> "Browse", "listId" -> "cd7c2c7a-00f6-4035-867f-d1dd7d89972d_6625365X3XX1505943605585", "videoId" -> "80000778", "rank" -> 0, "row" -> 0, "requestId" -> "ac12f4e1-5644-46af-87d1-ec3b92ce4896-4071171"), "id" -> 8697374208897843L, "sequence" -> 136, "time" -> 527637405129L, "type" -> List("Play", "Action", "Session")))

val onlyWithTrackingInfo =
  list.filter(_.contains("trackingInfo"))

打印onlyWithTrackingInfo会输出以下内容(美化):

List(
  Map(
    trackingInfo -> Map(trackId -> 14170286, location -> Browse, listId -> cd7c2c7a-00f6-4035-867f-d1dd7d89972d_6625365X3XX1505943605585, videoId -> 80000778, rank -> 0, row -> 0, requestId -> ac12f4e1-5644-46af-87d1-ec3b92ce4896-4071171), 
    id -> 8697374208897843,
    sequence -> 136,
    time -> 527637405129,
    type -> List(Play, Action, Session)
  )
)

答案 1 :(得分:0)

一种方法是collect由所需密钥组成的任何Map

def extract(list: List[Map[String, Any]], key: String) = list.collect{
  case m if m.get(key) != None => m
}

val list1: List[Map[String, Any]] = List(
  Map("sequence" -> 192, "id" -> 8697413670252052L, "type" -> List("AimLowEvent", "DiscreteEvent"), "time" -> 527638582195L)
)

val list2: List[Map[String, Any]] = List(
  Map("duration" -> 143858743, "id" -> 8702168014834892L, "sequence" -> 195, "sessionId" -> 8697344444103393L, "time" -> 527780267698L, "type" -> List("SessionCanceled", "SessionEnded")),
  Map("trackingInfo" -> Map("trackId" -> 14170286, "location" -> "Browse", "listId" -> "cd7c2c7a-00f6-4035-867f-d1dd7d89972d_6625365X3XX1505943605585", "videoId" -> 80000778, "rank" -> 0, "row" -> 0, "requestId" -> "ac12f4e1-5644-46af-87d1-ec3b92ce4896-4071171"), "id" -> 8697344444103393L, "sequence" -> 89, "time" -> 527636408955L, "type" -> List("Play", "Action", "Session"))
)

extract(list1, "trackingInfo")
// res1: List[Map[String,Any]] = List()

extract(list2, "trackingInfo")
// res2: List[Map[String,Any]] = List(
//  Map(trackingInfo -> Map(trackId -> 14170286, location -> Browse, listId -> cd7c2c7a-00f6-4035-867f-d1dd7d89972d_6625365X3XX1505943605585, videoId -> 80000778, rank -> 0, row -> 0, requestId -> ac12f4e1-5644-46af-87d1-ec3b92ce4896-4071171), id -> 8697344444103393, sequence -> 89, time -> 527636408955, type -> List(Play, Action, Session))
// )