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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With