Can we do a conditional chain in Kotlin? or ignore...
# getting-started
z
Can we do a conditional chain in Kotlin? or ignore it and go to the next operator?
Copy code
private fun simulateFixtures(list: List<List<Team>>) = list.map { fixture ->
    fixture.toList().random()
}.shuffled().chunked(2)
s
Can you give a bit more detail? Not sure what your example code is trying to convey
⬆️ 2
My first thought on reading your message is it sounds like a job for Arrow though
s
based on that StackOverflow thread, I would say the canonical solution is something like:
Copy code
foo.let {
    if (somePredicate) it.doSomething() else it
}
Does that match what you're trying to do? Are you just looking for a shorter way to write it?
👍 1
z
That matches
s
I think you'll struggle to find a more concise and readable way to write it than
let
+ `if`/`else`
👍 1
It is a bit wordy though 😞
The
else it
on the end is particularly cumbersome
j
What part do you want to run conditionally? All operations look general enough to be done in one go. If you have only 1 fixture in the list passed as argument, you wouldn't even need to call this method, because you would just pick the winner and the result would not be a list or 2-element lists anyway
Also, you have a
List<List<Team>>
, you don't need
toList()
before using
random()
on an element. It's already a list, and you don't need a copy just to choose a random element out of it.
m
@Sam well, the kotlin devs have explicitely not added the ternary operator:
condition ? onTrue : onFalse
a
If you tend to often write code like:
kotlin Copy code
something
    .let { if (condition1) block1(it) else it }
    .let { if (condition2) block2(it) else it }
I suggest adding these custom scope extension functions to your arsenal:
kotlin Copy code
inline fun <T> T.letIf(condition: Boolean, block: (T) -> T): T =
    if (condition) this.let(block) else this

inline fun <T> T.runIf(condition: Boolean, block: T.() -> T): T =
    if (condition) this.run(block) else this

inline fun <T> T.alsoIf(condition: Boolean, block: (T) -> Unit): T =
    if (condition) this.also(block) else this

inline fun <T> T.applyIf(condition: Boolean, block: T.() -> Unit): T =
    if (condition) this.apply(block) else this
Then you could use them like this:
kotlin Copy code
import my.cool.extensions.letIf

something
    .letIf (condition1) { block1(it) }
    .letIf (condition2) { block2(it) }
e
first, a more useful signature would be
Copy code
inline fun <T : R, R> T.letIf(condition: Boolean, block: (T) -> R): R =
    if (condition) this.let(block) else this
second, that type of extension is waiting for https://youtrack.jetbrains.com/issue/KT-32993
191 Views