Home > database >  How can I improve the verbose code when I use enum in Kotlin?
How can I improve the verbose code when I use enum in Kotlin?

Time:05-09

The are many items in a enum class , I found there ae many verbose code in the function fun getLevel.

How can I improve it?

Code A

enum class ELevel(private val labelId: Int, val alarmed: Boolean){

   Normal(R.string.Normal,false),
   Leaves(R.string.Leaves,false),
   Whispering(R.string.Whispering,false),
   Quiet(R.string.Quiet,false),
   Refrigerator(R.string.Refrigerator,false),
   Electric(R.string.Electric,false),
   Washing(R.string.Washing,true),
   Alarm(R.string.Alarm,true),
   Subway(R.string.Subway ,true),
   Factory(R.string.Factory,true),
   Car(R.string.Car,true),
   Ambulance(R.string.Ambulance,true);

   fun getLabel(mContext: Context) =  mContext.getString(labelId)

   companion object {
        fun getLevel(soundValue: Double): ELevel {
            var temp = Normal
            val i = soundValue.toInt()

            if (i in 1..10) {
                temp = Normal
            }

            if (i in 11..20) {
                temp =  Leaves
            }

            ...

            if (i in 101..110) {
                temp = Car
            }

            if (i in 111..120) {
                temp =  Ambulance
            }


            return temp
        }
   }

CodePudding user response:

In the same way that you have associates a labelId and alarmed flag with each of the enum constants, you can add an additional maxSoundLevel property:

enum class ELevel(
    private val labelId: Int,
    val alarmed: Boolean,
    val maxSoundLevel: Int,
){

    Normal(R.string.Normal,false, 10),
    Leaves(R.string.Leaves,false, 20),
    ...
}

Then you can do:

companion object {
    fun getLevel(soundValue: Double): ELevel =
        // assuming the max sound levels are in ascending order
        values().firstOrNull { soundValue.toInt() <= it.maxSoundLevel }
            // if there is no match, throw exception. You can also just return the nullable ELevel
            ?: throw IllegalArgumentException("Unknown sound")
}

CodePudding user response:

One way could be to create an abstract val range and define it for each enum. After that you could simply check and get the first enum that have your soundValue in his range.

enum class ELevel(private val labelId: Int, val alarmed: Boolean) {

    Normal(R.string.Normal, false) {
        override val range: IntRange = 1..10
    },
    Leaves(R.string.Leaves, false) {
        override val range: IntRange = 11..20
    },
    Whispering(R.string.Whispering, false) {
        override val range: IntRange = ...
    },
    Quiet(R.string.Quiet, false) {
        override val range: IntRange = ...
    },
    Refrigerator(R.string.Refrigerator, false) {
        override val range: IntRange = ...
    },
    Electric(R.string.Electric, false){
        override val range: IntRange = ...
    },
    Washing(R.string.Washing, true){
        override val range: IntRange = ...
    },
    Alarm(R.string.Alarm, true){
        override val range: IntRange = ...
    },
    Subway(R.string.Subway, true){
        override val range: IntRange = ...
    },
    Factory(R.string.Factory, true){
        override val range: IntRange = ...
    },
    Car(R.string.Car, true) {
        override val range: IntRange = 101..110
    },
    Ambulance(R.string.Ambulance, true) {
        override val range: IntRange = 111..120
    };

    fun getLabel(mContext: Context) = mContext.getString(labelId)

    abstract val range: IntRange

    companion object {
        fun getLevel(soundValue: Double): ELevel =
            values().first { it.range.contains(soundValue.toInt()) }
    }
}

CodePudding user response:

If the IDs of the Strings are exact matches for the enum value names, you can also use identifier look-up to shorten your code a little bit more.

enum class ELevel(
    val alarmed: Boolean,
    private val maxSoundLevel: Int,
){

    Normal(false, 10),
    Leaves(false, 20),
    //...
    ;

    private var labelId = 0

    fun getLabel(context: Context){
        if (labelId == 0) {
            labelId = context.resources.getIdentifier(name, "id", context.packageName)
        }
        return context.getString(labelId)
    }
}

  • Related