Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter and process hashmap entries in Kotlin

Tags:

hashmap

kotlin

I am probably missing something very obvious: How do I efficiently filter and iterate through the entries of a HashMap in Kotlin?

I want to do the following:

myMap.filterValues{ someCondition }.forEach { doSomethingWithTheEntry }

How can I avoid the creation of intermediate objects? filterValues will create a HashMap, which is not really needed here.

I could of course write

myMap.forEach { if(someCondition) doSomethingWithTheEntry }

but the functional-style filter approach looks more elegant.

like image 409
trunklop Avatar asked Mar 05 '18 11:03

trunklop


People also ask

How do you filter a map in Kotlin?

There are also two specific ways for filtering maps: by keys and by values. For each way, there is a function: filterKeys() and filterValues() . Both return a new map of entries which match the given predicate. The predicate for filterKeys() checks only the element keys, the one for filterValues() checks only values.

How do I filter data with Kotlin?

If you want to use element positions in the filter, use filterIndexed() . It takes a predicate with two arguments: the index and the value of an element. To filter collections by negative conditions, use filterNot() . It returns a list of elements for which the predicate yields false .

How does HashMap work in Kotlin?

Kotlin HashMap is a collection which contains pairs of object. Kotlin Hash Table based implementation of the MutableMap interface. It stores the data in the form of key and value pair. Map keys are unique and the map holds only one value for each key.


1 Answers

To avoid storing intermediate values, you can use Sequence, which is somewhat a lazy equivalent of Iterable (see another Q&A for details).

To process the entries of a Map as a Sequence, convert it with .asSequence() (again, no intermediate collection is created) and then use .filter { ... } and .forEach { ... } on the sequence:

myMap.asSequence().filter { someCondition(it) }.forEach { doSomething(it) }

This will create a pipeline which will query the entries one by one, check the predicate on them and, if matched, run the action, without storing the intermediate values.

Efficiency, however, depends on the collection size and the complexity of the operations, because the laziness of Sequence does not come for free: it introduces some overhead, which may become considerable if you only run simple transformations of small collections in performance-critical code.

like image 121
hotkey Avatar answered Oct 12 '22 16:10

hotkey