I\'m trying to find the best way to do a \'reverse lookup\' on an enum in Kotlin. One of my takeaways from Effective Java was that you introduce a static map inside the enum
True Idiomatic Kotlin Way. Without bloated reflection code:
interface Identifiable<T : Number> {
val id: T
}
abstract class GettableById<T, R>(values: Array<R>) where T : Number, R : Enum<R>, R : Identifiable<T> {
private val idToValue: Map<T, R> = values.associateBy { it.id }
operator fun get(id: T): R = getById(id)
fun getById(id: T): R = idToValue.getValue(id)
}
enum class DataType(override val id: Short): Identifiable<Short> {
INT(1), FLOAT(2), STRING(3);
companion object: GettableById<Short, DataType>(values())
}
fun main() {
println(DataType.getById(1))
// or
println(DataType[2])
}
val t = Type.values()[ordinal]
:)
Another example implementation. This also sets the default value (here to OPEN
) if no the input matches no enum option:
enum class Status(val status: Int) {
OPEN(1),
CLOSED(2);
companion object {
@JvmStatic
fun fromInt(status: Int): Status =
values().find { value -> value.status == status } ?: OPEN
}
}
Came up with a more generic solution
inline fun <reified T : Enum<*>> findEnumConstantFromProperty(predicate: (T) -> Boolean): T? =
T::class.java.enumConstants?.find(predicate)
Example usage:
findEnumConstantFromProperty<Type> { it.value == 1 } // Equals Type.A
Another option, that could be considered more "idiomatic", would be the following:
companion object {
private val map = Type.values().associateBy(Type::value)
operator fun get(value: Int) = map[value]
}
Which can then be used like Type[type]
.
First of all, the argument of fromInt()
should be an Int
, not an Int?
. Trying to get a Type
using null will obviously lead to null, and a caller shouldn't even try doing that. The Map
has also no reason to be mutable. The code can be reduced to:
companion object {
private val map = Type.values().associateBy(Type::value)
fun fromInt(type: Int) = map[type]
}
That code is so short that, frankly, I'm not sure it's worth trying to find a reusable solution.