> if an entry isn’t in the base map, it won’t ...
# codereview
k
if an entry isn’t in the base map, it won’t exist in the final one
Yes. Which is why I iterated through
mapOverride
instead. This is a union of both maps with the assumption that they only contain sets/other values and a key always points to values of similar type (or null) in both maps. Entries in
mapOverride
are always preferred except for sets where both will get merged I suppose that is what you’re trying to achieve?
d
Exactly.
I have one more type to add here:
Map<String, Set<String>>
... and all these erased types makes it more complicated than it should be...
The original is from a json document that has "common" and "conditional" keys and each of them is an object that has a { key -> one of the three types, ... }. conditional needs to be merged over common.
k
I have one more type to add here:
Map<String, Set<String>>
You mean this as input? The
mergeWith
will handle it as well
one of the three types
I’m assuming this is
String
,
Set<String>
and
null
? 🤔
d
Map<String, Map<String, Set<String>>>
k
Aha. Okay
What should happen in this case?
d
Any key that exists in override should just reset the set (not add to it...)
Like by the String type.
That's why I started with all those casts...
k
This should do that:
Copy code
fun MutableMap<String, Any>.mergeWith(mapOverride: Map<String, Any>?) {
    mapOverride?.forEach { (k, v) ->
        val baseValue = this[k]
        this[k] = when {
            baseValue is Set<*> && v is Set<*> -> baseValue + v
            baseValue is Map<*, *> && v is Map<*, *> -> baseValue + v
            else -> v
        }
    }
}
You’d notice I used
+
in both cases. That’s fine, since the operands are of different types, the operator resolves to different methods, as it applies to
Set
and
Map
accordingly
d
Cool! But then, when a key is in override that isn't in base...?
k
…then it will add it to base
d
Very nice 😁, thanks alot!
k
You’re welcome! 🙂