Reputation: 2908
I have the following datastructure:
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)))
Whats the best way to merge these maps so that the resulting object would be the following:
Map(1365094146000000 -> Map(latitude -> 45.30397, longitude -> -75.89806),
1365094752000000 -> Map(latitude -> 45.30405, longitude -> -75.89806))
Thanks
Upvotes: 1
Views: 233
Reputation: 53348
Scalaz provides a nice way to do what you want:
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))
Search for "semigroup" for more information on how the code works.
Upvotes: 0
Reputation: 236
Another possibility:
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)
}
Upvotes: 2
Reputation: 10667
As for the input structure, latitude
and longtitude
should be strings. Also, the timestamps should be Longs as they're out of Int
's range. For instance,
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)))
Once that's fixed, you can do:
yourList.flatten.groupBy(_._1) map { case (key, value) => key -> value.map(_._2).flatten.toMap } toMap
First, this merges the two Maps together. Then, it groups the entries by the timestamp to form Map[Long,List[(Long, Map[String,Double])]]
. After that, we're almost at the solution and just have to get rid of the timestamp duplication in the value (value.map(_._2)
), flatten latitudes and longitudes, and convert them to a Map
. Finally, we convert the output from a List
to a Map
.
The expanded version with types looks like this:
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
Upvotes: 3