从Map [String,Any]中提取值,其中Any是Map本身

时间:2017-10-11 12:09:59

标签: scala scala-collections

我有一个Map,其值字段中包含另一个Map。这是一些记录的例子;

(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]会让我陷入从中提取价值的难题。

感谢任何帮助

1 个答案:

答案 0 :(得分: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这样的密钥有点安全。你应该实施更严格的方法。