Conceptual question here. I have a class which contains a list. Whenever the size of the list is 1, I want certain functions to be used, and when it's greater than 1, I want alternative functions (which serve the same purpose but do something a bit different) to be used. (it's a Java swing app in kotlin so lots of gui stuff). What sort of structure should I use to keep this organized?
c
Chris Lee
11/18/2022, 2:56 PM
One option:
Copy code
when(list.size()) {
1 -> doSingletonThing()
else -> doOtherThings() // should 0 be a special case?
}
j
Joshua Hansen
11/18/2022, 2:57 PM
Yeah that works for one function call, but I don't want a bunch of when blocks all over the place.
c
Chris Lee
11/18/2022, 2:58 PM
place it in the class itself, or an extension function as appropriate.
e
ephemient
11/18/2022, 2:59 PM
Copy code
interface DoThings {
fun doThingA()
fun doThingB()
}
class SingleDoThings(val item: T) { override ... }
class MultiDoThings(val items: List<T>) { override ... }
fun DoThings(items: List<T>): DoThings =
items.singleOrNull()?.let { SingleDoThings(it) }
?: MultiDoThings(items)
k
Kirill Grouchnikov
11/18/2022, 4:07 PM
Why overcomplicate instead of using a simple if/else?
s
Stephan Schröder
11/19/2022, 12:44 PM
assuming your list is immutable once it is used to initialise the instance, you could use a sealed class/interface:
Copy code
sealed class SomeThing {
abstract fun doSomething()
private data class Single(private val item:String): SomeThing() {
override fun doSomething() {
println("single item: $item")
}
}
private data class Multi(private val moreThanOneItem: List<String>): SomeThing() {
override fun doSomething() {
println("multiple items: $moreThanOneItem")
}
}
companion object {
fun new(items: List<String>): SomeThing = when(items.size) {
0 -> error("can't instanciate a SomeThing with an empty list")
1 -> SomeThing.Single(items.single())
else -> SomeThing.Multi(items)
}
}
}