Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge maps by key

Say I have two maps:

val a = Map(1 -> "one", 2 -> "two", 3 -> "three") val b = Map(1 -> "un", 2 -> "deux", 3 -> "trois") 

I want to merge these maps by key, applying some function to collect the values (in this particular case I want to collect them into a seq, giving:

val c = Map(1 -> Seq("one", "un"), 2 -> Seq("two", "deux"), 3 -> Seq("three", "trois")) 

It feels like there should be a nice, idiomatic way of doing this.

like image 903
Submonoid Avatar asked Oct 13 '11 13:10

Submonoid


People also ask

How do I merge two maps together?

concat() Alternatively, we can use Stream#concat() function to merge the maps together. This function can combine two different streams into one. As shown in the snippet, we are passed the streams of map1 and map2 to the concate() function and then collected the stream of their combined entry elements.

How do I merge two maps in groovy?

The easiest way to merge two maps in Groovy is to use + operator. This method is straightforward - it creates a new map from the left-hand-side and right-hand-side maps.

How do I merge two maps in typescript?

Explicitly type the keys and values of the third Map. Use the spread syntax (...) to unpack the key-value pairs of the first two Maps. The types of the keys and values of the Maps have to match.

How can I combine two Hashmap objects containing the different types?

Assuming that both maps contain the same set of keys, and that you want to "combine" the values, the thing you would be looking for is a Pair class, see here for example. You simply iterate one of the maps; and retrieve values from both maps; and create a Pair; and push that in your result map.


1 Answers

scala.collection.immutable.IntMap has an intersectionWith method that does precisely what you want (I believe):

import scala.collection.immutable.IntMap  val a = IntMap(1 -> "one", 2 -> "two", 3 -> "three", 4 -> "four") val b = IntMap(1 -> "un", 2 -> "deux", 3 -> "trois")  val merged = a.intersectionWith(b, (_, av, bv: String) => Seq(av, bv)) 

This gives you IntMap(1 -> List(one, un), 2 -> List(two, deux), 3 -> List(three, trois)). Note that it correctly ignores the key that only occurs in a.

As a side note: I've often found myself wanting the unionWith, intersectionWith, etc. functions from Haskell's Data.Map in Scala. I don't think there's any principled reason that they should only be available on IntMap, instead of in the base collection.Map trait.

like image 151
Travis Brown Avatar answered Nov 13 '22 06:11

Travis Brown