I’m writing a function to merge two Map’s together. This is what I have so far:
def merge[K, V1, V2, V3](left: Map[K, V1], right: Map[K, V2])
(fn: (Option[V1], Option[V2]) => V3): Map[K, V3] = {
val r = (left.keySet ++ right.keySet) map {
key =>
(key -> fn(left.get(key), right.get(key)))
}
r.toMap
}
The function itself works. You use the function as so:
val m1 = Map(1 -> "one", 3 -> "three", 5 -> "five")
val m2 = Map(1 -> "I", 5 -> "V", 10 -> "X")
merge(m1, m2) { (_, _) }
// returns:
// Map(1 -> (Some(one),Some(I)),
// 3 -> (Some(three),None),
// 5 -> (Some(five),Some(V)),
// 10 -> (None,Some(X)))
I have two questions:
- I’m worried about the
performancecomputational complexity of the.getand.toMapcalls. Can anyone improve the implementation? - I’d like the default function to make a pair of the values (
{ (_, _) }). I can’t quite get the syntax to do so properly.
Edit:
While I originally said performance, I meant computational complexity. My guess is that this function performs in O(n•ln(n)) time. Looks like my function performs roughly in O(n). Can it be done in O(ln(n))?
For the default function literal use:
You’ll have to use merge like this:
merge(m1,m2)()I would say don’t be worried about performance until you perform some measurements on actual data.
Edit: about performance, by providing a view instead of constructing a map you can get quick “construction” at the expense of lookup – assuming we are dealing with immutable maps. So depending on actual data and use case, you can get better performance for certain operations, but it has a trade-off.