Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: Retain, replace or remove each map entry in-place

I have a mutable map (a LinkedHashMap to be specific) in Kotlin. For each map entry, I want to conditionally perform one of three actions:

  • Retain the entry as-is
  • Replace the entry's value
  • Remove the entry

In old Java, I would probably use an Iterator over the map's entrySet() for this purpose (using Iterator.remove() or Entry.setValue() accordingly). However, I wondered if there is a more elegant, functional approach present in Kotlin to do the same (i.e. apply a lambda to each entry in-place, similar to using replaceAll(), but with the ability to also remove entries).


In Kotlin, the following combination of replaceAll() and retainAll() does the same thing:

val map = LinkedHashMap<String,Int>(mapOf("a" to 1, "b" to 2, "c" to 3))
map.replaceAll { key, value ->
    if(key.startsWith("a")) {
        value * 2
    } else {
        value
    }
}
map.entries.retainAll { entry ->
    entry.key.startsWith("a") || entry.key.startsWith("b")
}

However, this iterates the map twice and requires splitting up the predicate/transformation. I would prefer a compute()-style all-in-one solution, just for all entries.

like image 766
Cybran Avatar asked Sep 11 '19 16:09

Cybran


People also ask

Does Kotlin map preserve order?

Yes, it will. The reference for mutableMapOf() says: The returned map preserves the entry iteration order. This is exactly the property that you asked about.

How do I remove items from Kotlin map?

The standard solution is to remove a key from a Map in Kotlin is using the remove() function. When the remove() function is called upon a key k , the mapping from key k to value v is removed from the map.

How do I change a value in Kotlin map?

Using replaceAll() function To apply a function to each entry of a Map in Kotlin, you can use the replaceAll() function that replaces each entry's value with the result of invoking the given function on that entry.

What is mapOf in Kotlin?

The kotlin mapOf is defined as the function and it is one of the util collections and it is denoted under the interface it accepts keys and values for the user-defined types the key based mapped values are processing at the capabilities for to store and retrieving the values with the help of specific keys it also been ...


1 Answers

In functional world, immutability is an essential principle. So in-place modifications are not convenient.

But if you prefer an in-place approach, possible options are retainAll or removeAll to filter items. For in-place replacement you need to iterate the collection. You can use forEach to do an in-place modification:

data class User(val name: String)

val users = mutableListOf( User("John"), User("Alice"), User("Bob") )
numbers.run{
    removeAll { it.name == "Alice" }
    forEach { it.name =  "Mr. ${it.name}"}
} 
like image 109
Fartab Avatar answered Nov 09 '22 06:11

Fartab