Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create an enum from a string in Kotlin?

Tags:

kotlin

I have an enum with some instances Foo and Bar. If I have a string "Foo", how can I instantiate a Foo enum from that? In C# it would be Enum.Parse(...), is there an equivalent in Kotlin?

Currently, the best I have found is to create a factory that switches on all possible strings, but that is error prone and performs poorly for large enumerations.

like image 830
Micah Zoltu Avatar asked Feb 16 '15 18:02

Micah Zoltu


People also ask

How do I get enum from string Kotlin?

To get an enum constant by its string value, you can use the function valueOf() on the Enum class. It helps us to get enum from a String value in Kotlin.

How do I convert string to enum?

Use the Enum. IsDefined() method to check if a given string name or integer value is defined in a specified enumeration. Thus, the conversion of String to Enum can be implemented using the Enum. Parse ( ) and Enum.

Can you have an enum of strings?

Create Enumeration of Strings With Extension Function in C# There is no built-in method of declaring an enumeration with string values. If we want to declare an enumeration with string constants, we can use the enum class and an extension function to achieve this goal.


5 Answers

Kotlin enum classes have "static" function valueOf to get enum entry by string(like Java enums). Additionally they have "static" function values to get all enum entries. Example:

enum class MyEnum {
  Foo, Bar, Baz
}

fun main(args : Array<String>) {
  println(MyEnum.valueOf("Foo") == MyEnum.Foo)
  println(MyEnum.valueOf("Bar") == MyEnum.Bar)
  println(MyEnum.values().toList())
}
like image 101
bashor Avatar answered Oct 04 '22 08:10

bashor


As bashor suggested, use MyEnum.valueOf() but please have in mind that it throws an exception if value can't be found. I recommend using:

enum class MyEnum {
  Foo, Bar, Baz
}

try {
   myVar = MyEnum.valueOf("Qux")
} catch(e: IllegalArgumentException) {
   Log.d(TAG, "INVALID MyEnum value: 'Qux' | $e")
}
like image 27
Paul Ardeleanu Avatar answered Oct 04 '22 08:10

Paul Ardeleanu


Would do it like

enum class MyEnum {
  Foo, Bar, Baz
}

val value = MyEnum.values().firstOrNull {it.name == "Foo"} // results to MyEnum.Foo
like image 23
Nordmeyer Avatar answered Oct 03 '22 08:10

Nordmeyer


Reusable Exception Safe Solution

The default solution in Kotlin will throw an exception. If you want a reliable solution that works statically for all enums, try this!

Now just call valueOf<MyEnum>("value"). If the type is invalid, you'll get null and have to handle it, instead of an exception.

inline fun <reified T : Enum<T>> valueOf(type: String): T? {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: Exception) {
        null
    }
}

Alternatively, you can set a default value, calling valueOf<MyEnum>("value", MyEnum.FALLBACK), and avoid a null response. You can extend your specific enum to have the default be automatic

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: Exception) {
        default
    }
}

Or if you want both, make the second:

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T = valueOf<T>(type) ?: default
like image 33
Gibolt Avatar answered Oct 02 '22 08:10

Gibolt


If you want to create an enum value from one of its parameters, instead of the name, this funny code does a pretty decent job:

inline fun <reified T : Enum<T>, V> ((T) -> V).find(value: V): T? {
    return enumValues<T>().firstOrNull { this(it) == value }
}

This can be used like this:

enum class Algorithms(val string: String) {
    Sha1("SHA-1"),
    Sha256("SHA-256"),
}

fun main() = println(
    Algorithms::string.find("SHA-256")
            ?: throw IllegalArgumentException("Bad algorithm string: SHA-256")
)

This will print Sha256

like image 33
squirrel Avatar answered Oct 03 '22 08:10

squirrel