2017-10-11 31 views
1

我有一个地图,其中包含另一个地图的值字段。这是一些记录的例子;从地图[字符串,任何]提取值其中任何一个地图本身

(8702168053422489,Map(sequence -> 5, id -> 8702168053422489, type -> List(AppExperience, Session), time -> 527780267713)) 
(8702170626376335,Map(trackingInfo -> Map(trackId -> 14183197, location -> Browse, listId -> 3393626f-98e3-4973-8d38-6b2fb17454b5_27331247X28X6839X1506087469573, videoId -> 80161702, rank -> 0, row -> 1, imageKey -> boxshot|AD_e01f4a50-7e2b-11e7-a327-12789459b73e|en, requestId -> 662d92c2-6a1c-41a6-8ac4-bf2ae9f1ce68-417037), id -> 8702170626376335, sequence -> 59, time -> 527780275219, type -> List(NavigationLevel, Session), view -> details)) 
(8702168347359313,Map(muting -> false, id -> 8702168347359313, level -> 1, type -> List(Volume))) 
(8702168321522401,Map(utcOffset -> 3600, type -> List(TimeZone), id -> 8702168321522401)) 
(8702171157207449,Map(trackingInfo -> Map(trackId -> 14183197, location -> Browse, listId -> 3393626f-98e3-4973-8d38-6b2fb17454b5_27331247X28X6839X1506087469573, videoId -> 80161356, rank -> 0, row -> 1, imageKey -> boxshot|AD_e01f4a50-7e2b-11e7-a327-12789459b73e|en, requestId -> 662d92c2-6a1c-41a6-8ac4-bf2ae9f1ce68-417037), id -> 8702171157207449, sequence -> 72, startOffset -> 0, time -> 527780278061, type -> List(StartPlay, Action, Session))) 

实际记录我所感兴趣的是包含trackingInfo,记录2和5

我希望做的是提取那些,然后从那里提取等一些键的那些作为trackId。像这样的东西;

val trackingInfo = json("trackingInfo").asInstanceOf[Map[String, Any]] 
val videoId = trackingInfo("videoId").asInstanceOf[Int] 
val id = json("id").asInstanceOf[Long] 
val sequence = json("sequence").asInstanceOf[Int] 
val time = json("time").asInstanceOf[Long] 
val eventType = json.get("type").getOrElse(List("")).asInstanceOf[List[String]] 

为了提取内图,我累了; myMap.map {case (k,v: collection.Map[_,_]) => v.toMap case _ => }

这带来了内部的地图,但作为scala.collection.immutable.Iterable[Any]这使我在从中提取值的困惑。

任何帮助表示赞赏

+0

只是一般性评论。使用.asInstanceOf不安全。可能导致问题 – Pavel

回答

1

比方说,你有一个真正的地图(我把它剪一点点)

val data: Map[ BigInt, Any ] = Map(
    BigInt(8702168053422489L) -> Map("sequence" -> "5", "id" -> BigInt(8702168053422489L)), 
    BigInt(8702170626376335L) -> Map("trackingInfo" -> Map("trackId" -> BigInt(14183197), "location" -> "Browse"), "id" -> BigInt(8702170626376335L)), 
    BigInt(8702168347359313L) -> Map("id" -> BigInt(8702168347359313L)), 
    BigInt(8702168321522401L) -> Map("id" -> BigInt(8702168321522401L)), 
    BigInt(8702171157207449L) -> Map("trackingInfo" -> Map("trackId" -> BigInt(14183197), "location" -> "Browse"), "id" -> BigInt(8702171157207449L)) 
) 

你想其中有一个trackingInfo关键

val onlyWithTracking = data.filter((row) => { 

    val recordToFilter = row._2 match { 
     case trackRecord: Map[ String, Any ] => trackRecord 
     case _ => Map("trackId" -> Map()) 
    } 

    recordToFilter.contains("trackingInfo") 
}) 
记录

然后以某种方式处理这些记录

onlyWithTracking.foreach((row) => { 

    val record = row._2 match { 
     case trackRecord: Map[ String, Any ] => trackRecord 
     case _ => Map("trackingInfo" -> Map()) 
    } 

    val trackingInfo = record("trackingInfo") match { 
     case trackRow: Map[ String, Any ] => trackRow 
     case _ => Map("trackId" -> "error") 
    } 

    val trackId = trackingInfo("trackId") 

    println(trackId) 
}) 

使用此模式匹配我试图确保使用诸如trackingInfotrackId之类的密钥有点安全。你应该实施更严格的方法。

+0

感谢您的回复。不过请记住,原来的Map是'Map [String,Any]'所以当做'val onlyWithTracking = data.filter((row)=> row._2.contains(“trackingInfo”))'我得到错误'value contains不是任何成员' – ukbaz

+0

是的。我编辑了答案来解决这个问题。多一点模式匹配。 –

+0

谢谢你,我似乎得到这个错误处理位scala.math.BigInt不能转换为java.lang.String。 – ukbaz

相关问题