在scala中组合地图列表

时间:2013-04-05 21:19:42

标签: scala

我有以下数据结构:

List(Map(
    1365094146000000 -> Map(latitude -> 45.30397), 
    1365094752000000 -> Map(latitude -> 45.30405), 
    1365094449000000 -> Map(latitude -> 45.30412), 
    1365095351000000 -> Map(latitude -> 45.30400), 
    1365095054000000 -> Map(latitude -> 45.30400)), 
    Map(
    1365094146000000 -> Map(longitude -> -75.89806), 
    1365094752000000 -> Map(longitude -> -75.89806), 
    1365094449000000 -> Map(longitude -> -75.89811), 
    1365095351000000 -> Map(longitude -> -75.89804), 
    1365095054000000 -> Map(longitude -> -75.89809)))

什么是合并这些地图的最佳方式,以便生成的对象如下:

Map(1365094146000000 -> Map(latitude -> 45.30397, longitude -> -75.89806),
    1365094752000000 -> Map(latitude -> 45.30405, longitude -> -75.89806))

由于

3 个答案:

答案 0 :(得分:3)

对于输入结构,latitudelongtitude应该是字符串。此外,时间戳应为Longs,因为它们超出Int的范围。例如,

val lst = List(Map(
    1365094146000000l -> Map("latitude" -> 45.30397), 
    1365094752000000l -> Map("latitude" -> 45.30405), 
    1365094449000000l -> Map("latitude" -> 45.30412), 
    1365095351000000l -> Map("latitude" -> 45.30400), 
    1365095054000000l -> Map("latitude" -> 45.30400)), 
    Map(
    1365094146000000l -> Map("longitude" -> -75.89806), 
    1365094752000000l -> Map("longitude" -> -75.89806), 
    1365094449000000l -> Map("longitude" -> -75.89811), 
    1365095351000000l -> Map("longitude" -> -75.89804), 
    1365095054000000l -> Map("longitude" -> -75.89809)))

修复后,您可以:

yourList.flatten.groupBy(_._1) map { case (key, value) => key -> value.map(_._2).flatten.toMap } toMap

首先,这将两个地图合并在一起。然后,它按时间戳对条目进行分组,以形成Map[Long,List[(Long, Map[String,Double])]]。在那之后,我们几乎处于解决方案中,只需要去除值(value.map(_._2))中的时间戳重复,压缩纬度和经度,并将它们转换为Map。最后,我们将输出从List转换为Map

带有类型的扩展版本如下所示:

yourList.flatten.groupBy { x: (Long, Map[String, Double]) => 
    x._1 } map { case (key: Long, value: List[(Long, Map[String, Double])]) => 
        key -> value.map { x: (Long, Map[String, Double]) => 
            x._2 
        }.flatten.toMap 
    } toMap

答案 1 :(得分:2)

另一种可能性:

val latitude = "latitude"
val longitude = "longitude"

val data : List[Map[Long, Map[String, Double]]] = List(Map(
    1365094146000000L -> Map(latitude -> 45.30397),
    1365094752000000L -> Map(latitude -> 45.30405),
    1365094449000000L -> Map(latitude -> 45.30412),
    1365095351000000L -> Map(latitude -> 45.30400),
    1365095054000000L -> Map(latitude -> 45.30400)),
    Map(
    1365094146000000L -> Map(longitude -> -75.89806),
    1365094752000000L -> Map(longitude -> -75.89806),
    1365094449000000L -> Map(longitude -> -75.89811),
    1365095351000000L -> Map(longitude -> -75.89804),
    1365095054000000L -> Map(longitude -> -75.89809)))

 data match {
   case List(latmap, longmap) =>
     for ((key, vlat) <- latmap; vlong <- longmap.get(key)) yield (key, vlong ++ vlat)
 }

答案 2 :(得分:0)

Scalaz提供了一种很好的方式来做你想做的事情:

import scalaz._, Scalaz._

val lst = List(Map(
    1365094146000000l -> Map("latitude" -> 45.30397), 
    1365094752000000l -> Map("latitude" -> 45.30405), 
    1365094449000000l -> Map("latitude" -> 45.30412), 
    1365095351000000l -> Map("latitude" -> 45.30400), 
    1365095054000000l -> Map("latitude" -> 45.30400)), 
    Map(
    1365094146000000l -> Map("longitude" -> -75.89806), 
    1365094752000000l -> Map("longitude" -> -75.89806), 
    1365094449000000l -> Map("longitude" -> -75.89811), 
    1365095351000000l -> Map("longitude" -> -75.89804), 
    1365095054000000l -> Map("longitude" -> -75.89809)))

scala> lst(0) |+| lst(1) foreach println
(1365094146000000,Map(longitude -> -75.89806, latitude -> 45.30397))
(1365094752000000,Map(longitude -> -75.89806, latitude -> 45.30405))
(1365094449000000,Map(longitude -> -75.89811, latitude -> 45.30412))
(1365095351000000,Map(longitude -> -75.89804, latitude -> 45.304))
(1365095054000000,Map(longitude -> -75.89809, latitude -> 45.304))

搜索&#34; semigroup&#34;有关代码如何工作的更多信息。