Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: replace 'cascade if' with 'when' comparing with other variables

I'm starting with Kotlin and I'm facing a problem. I have three constants (let's call them VAL_A, VAL_B and VAL_C) and I'm doing this assignation:

var variable = if (value < VAR_A) {
            valueA
        } else if (value <= VAR_B) {
            valueB
        } else if (value <= VAR_C) {
            valueC
        } else {
            valueD
        }

I want to use a when block instead of the if else, but I don't know how to do the value < VAR_A and the value > VAR_C ones.

Thank you and sorry about my English!

like image 716
DAA Avatar asked May 03 '18 19:05

DAA


3 Answers

The ideal syntax you may be looking for is

when (value) {
    < valueA -> valueA
    <= valueB -> valueB
    <= valueC -> valueC
    else -> valueD
}

Unfortunately, this isn't possible because the comparison operators are operator overloads for functions requiring a receiver:

value < valueA

is the same as

value.compareTo(valueA) < 0

Because compareTo is not a keyword like is or in (as used in zsmb13's answer), you would need to create this when block:

when {
    value < valueA -> valueA
    value <= valueB -> valueB
    value <= valueC -> valueC
    else -> valueD
}

Kotlin is full of wonderful things. You could adventure into some alternative solutions that don't use a cascading conditional at all. It looks to me like you want value to round up to the nearest of valueA, valueB, valueC, and valueD. So, for example, an alternative may be:

var variable = listOf(valueA, valueB, valueC, valueD).sorted().first { value <= it }

This will choose the closest value larger than value from the set and assign it to variable.

like image 116
M. Palsich Avatar answered Sep 20 '22 19:09

M. Palsich


This should be the simplest equivalent of your if expression:

var variable = when {
    value < VAR_A -> valueA
    value <= VAR_B -> valueB
    value <= VAR_C -> valueC
    else -> valueD
}
like image 34
s1m0nw1 Avatar answered Sep 19 '22 19:09

s1m0nw1


If, for example, it's true that 0 < VAR_A < VAR_B < VAR_C, you could do this:

var variable = when (value) {
    in 0..VAR_A -> valueA
    in VAR_A..VAR_B -> valueB
    in VAR_B..VAR_C -> valueC
    else -> valueD
}

But perhaps this is the most legible form of when for this task:

var variable = when {
    value <= VAR_A -> valueA
    value <= VAR_B -> valueB
    value <= VAR_C -> valueC
    else -> valueD
}
like image 24
zsmb13 Avatar answered Sep 20 '22 19:09

zsmb13