I need to obtain some string that match with another. For example, when my string is “Ne” I need to obtain “Neon”. I made this, but I think that this isn’t the best way. I think that is better use sealed class. Is there some way to match a string with an element from a sealed class?
fun getName(symbol: String): String{
return when(symbol){
"Ne" -> {"Neon"}
"Ar" -> {"Argon"}
"Kr" -> {"Krypton"}
"Xe" -> {"Xenon"}
"Rn" -> {"Radon"}
"Br" -> {"Bromine"}
else -> {""}
}
}
thanks!
A sealed class probably won't help you much here, but an Enum could, especially if you later want to do more than just get the full name (e.g. get the atomic weight, localized string resource ID, or something too). It also provides you with a strong type, so you can define a function that takes an Element
enum instead of just a string.
enum class Element(val full_name: String, val num: Int) {
Ne("Neon", 10),
W( "Tungsten",74),
Fe("Iron", 26),
MISSING("", -1);
companion object {
// or just use Element.valueOf(), but this lets you make
// a MISSING entry to return instead if you want
fun fromSymbol(sym: String): Element {
return try {
valueOf(sym)
} catch(e: IllegalArgumentException) {
MISSING;
}
}
fun fromNumber(n: Int): Element {
return values().firstOrNull { it.num == n } ?: MISSING
}
}
}
This is more extensible than the when
approach because you can add extra attributes to the elements while keeping the single lookup. It acts like a sealed class (sort of) in that you cannot add any element that isn't defined in the enum.
Any attributes you add to the enum are available to use, like atomic number, weight, full name, or whatever else you want to add.
val e = Element.valueOf("Ne")
println("Element is ${e.full_name} - number ${e.num}")
// or
val e = Element.fromSymbol("Ne")
println("Element is ${e.full_name} - number ${e.num}")
// or
val e = Element.fromNumber(10)
println("Element is ${e.full_name} - number ${e.num}")
Using the companion object getters instead of Element.valueOf
also lets you do things like make the retrieval case-insensitive
fun fromSymbol(sym: String): Element {
return values().firstOrNull { it.name.lowercase() == sym.lowercase() } ?: MISSING
}
Localization
The enum approach could also be easily adapted in the future if you wanted to localize the element names. You could put the localized names in strings.xml files and set a resource ID in the enum instead of a raw string
enum class Element( val name_id: Int, val num: Int) {
Ne(R.string.neon,10),
Fe(R.string.iron,26);
fun getName(ctx: Context): String {
return ctx.getString(name_id)
}
companion object {
//...
}
}
val e = Element.fromSymbol("Ne")
println("Name is ${e.getName(ctx)}")