Skip to content

Instantly share code, notes, and snippets.

@cy6erGn0m
Created May 20, 2015 14:41
Show Gist options
  • Save cy6erGn0m/97ecdc7191364572a94a to your computer and use it in GitHub Desktop.
Save cy6erGn0m/97ecdc7191364572a94a to your computer and use it in GitHub Desktop.
Merge two maps with custom reduce function for Kotlin
private fun <K, V> Map<K, V>.mergeReduce(other: Map<K, V>, reduce: (V, V) -> V = { a, b -> b }): Map<K, V> {
val result = LinkedHashMap<K, V>(this.size() + other.size())
result.putAll(this)
other.forEach { e ->
val existing = result[e.key]
if (existing == null) {
result[e.key] = e.value
}
else {
result[e.key] = reduce(e.value, existing)
}
}
return result
}
@alamothe
Copy link

alamothe commented Nov 17, 2018

Based on @vickychijwani's but using Java's merge:

fun <K, V> Map<K, V>.mergeReduce(other: Map<K, V>, reduce: (V, V) -> V): Map<K, V> {
	val result = LinkedHashMap<K, V>(this)
	for ((key, value) in other) {
		result.merge(key, value, reduce)
	}
	return result
}

@geoffreywiseman
Copy link

geoffreywiseman commented Oct 11, 2019

I really liked the compactness of what @golonzovsky proposed, but I wanted:

  1. support for merging multiple maps without multiple toMutableMap() calls
  2. an in-place option if I already had a mutable map

So:

fun <K, V> Map<K, V>.mergeReduce(vararg others: Map<K, V>, reduce: (V, V) -> V): Map<K, V> =
		this.toMutableMap().apply { others.forEach { other -> other.forEach { merge(it.key, it.value, reduce) } } }

fun <K, V> MutableMap<K, V>.mergeReduceInPlace(vararg others: Map<K, V>, reduce: (V, V) -> V) =
		others.forEach { other -> other.forEach { merge(it.key, it.value, reduce) } }

@Woodz
Copy link

Woodz commented Oct 17, 2022

For those who are interested, this method is provided as part of https://github.com/LukasForst/katlib

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment