Enum Reverse Lookup in Kotlin
Problem
Kotlin offers the possibility to assign enumeration values to an enumeration type:
enum class Currency(val symbol: String) {
DOLLAR("$"),
EURO("€"),
POUND("£");
override fun toString(): String {return this.symbol}
}
Currency.valueOf("DOLLAR") // returns the enumeration value “$”
Currency.values().firstOrNull {currency -> currency.symbol == "$"} // returns the enumeration type DOLLAR
This kind of solution can be found searching the web in one way or another and it does what it is supposed to do. But do you want to iterate over all enumerations every time and compare values? What about a more elegant solution?
Solution
We extend our enumeration class with a Companion Object:
companion object {
private val mapping = values().associateBy(Currency::symbol)
fun fromSymbol(symbol: String) = mapping[symbol]
}
The function associateBy() returns a map<K, T>. More precisely a LinkedHashMap where K is the enumeration value and T is our enumeration type. The function "fromSymbol()" takes the enumeration value as argument and returns the matching enumeration type. Accessing the enumeration type via the enumeration value is no longer done by iterating in O(n), but by a hash lookup in the static map in O(1).
With this extension, the reverse lookup can be done as follows:
Currency.fromSymbol("$") // returns the enumeration type DOLLAR
This offers a solution with code, which is easier to read. This solution might even be more performant in terms of execution time.
Caution: If there is no 1 to 1 relation between enumeration types and enumeration values, this solution does not return the first hit but the last hit.
Further Aspects
- https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/enum-value-of.html
- https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/associate-by.html
---
Author: Andreas Hofmann / Software Engineer / Office Stuttgart
Download Toilet Paper #135: Enum Reverse Lookup in Kotlin (pdf)
Want to write the next ToiletPaper? Apply at jambit!