Gasan
12/19/2024, 11:20 AMnull, the only thing I came up with is this:
return if (createdChildren == null) {
deletedChildren
} else {
if (deletedChildren == null) {
createdChildren
} else {
createdChildren + createdChildren
}
}
is there an easier way to do this?Gasan
12/19/2024, 11:22 AMreturn when (createdChildren) {
null -> deletedChildren
else -> when (deletedChildren) {
null -> createdChildren
else -> createdChildren + createdChildren
}
}Gasan
12/19/2024, 11:24 AMreturn createdChildren + deletedChildren
but that does not workJulien Plissonneau Duquène
12/19/2024, 11:33 AMnull?Gasan
12/19/2024, 11:33 AMnullGasan
12/19/2024, 11:34 AMnullJaap Beetstra
12/19/2024, 11:34 AMorEmpty() to change a nullable List to an empty List. So then you can write
return listA.orEmpty() + listB.orEmpty()
(that would return an empty list if both are null)
Or, if you don’t want to add empty lists together you can use just one when:
return when {
listA == null -> listB
listB == null -> listA
else -> listA + listB
}Gasan
12/19/2024, 11:35 AMlistA + listB but still I like it 😄Gasan
12/19/2024, 11:39 AMJaap Beetstra
12/19/2024, 11:42 AMoperator fun <E> List<E>?.plus(o: List<E>?): List<E>? = when {
this == null -> o
o == null -> this
else -> this + o
}Gasan
12/19/2024, 11:43 AMGasan
12/19/2024, 11:45 AMJulien Plissonneau Duquène
12/19/2024, 11:46 AM+? operator ^ ^Gasan
12/19/2024, 11:53 AM+ reflects the meaning of what I want to doGasan
12/19/2024, 11:55 AMnull , kotlin can just use + operator of the optional typeGasan
12/19/2024, 11:57 AM+ for the non-null types should also accept null on the right operator and then return the left operator.Julien Plissonneau Duquène
12/19/2024, 1:54 PMlistOf("a").plus(null) will evaluate to a List<String?> with two elements "a" and nullJulien Plissonneau Duquène
12/19/2024, 1:54 PMnull.plus(...)Julien Plissonneau Duquène
12/19/2024, 2:08 PMplus() as it won't add elements but the whole list if the list itself is nullable:
println("a: " + (listOf<String?>("abc").plus(listOf("def", "ghi") as List<String?>)))
println("b: " + (listOf<String?>("abc").plus(listOf("def", "ghi") as List<String?>?)))
→
a: [abc, def, ghi]
b: [abc, [def, ghi]]
though the when blocks above would work correctlyGasan
12/19/2024, 3:58 PMdamian
12/19/2024, 5:49 PMlistOfNotNull(createdChildren, deletedChildren).reduceOrNull { l, r -> l + r }
Conveniently that would work for any number of lists as wellRuckus
12/19/2024, 6:32 PM+ operator, which is more complicated. For example, we want both of these to be true:
List<T> + T == List<T>
List<T> + List<T> == List<T>
But that's actually ambiguous. What if we have:
List<Any?> + List<Any?>?
That actually matches both cases (since List<Any?> is Any?), so which one takes precedence? And should that be resolved statically or dynamically? For example, say I have:
fun addThem(a: List<Any?>?, b: Any?) = a + b
and I call it with addThem(listOf(), listOf<Any?>()) . If I resolve the call statically, b is added as an element in a. If I resolve it dynamically, b is concatenated to a. Neither option is inherently more "correct" (it entirely depends on the use case). Now what happens if I call it with addThem(listOf(), null). Should I expect a list with one element more than a, or just a itself? Does that answer change if I do addThem(listOf(), null as List<Any>?)?
TL;DR: Your issue isn't with the concept of concatenating lists, it's with the ambiguity of using + to do it, so a named function would probably be a better option to make the intent clear (you could even make it an infix to so it's operator-like e.g.: List<T>? concat List<T>?).Gasan
12/19/2024, 6:50 PMunion , so the only thing to fix is to remove union logic from + operator :DRuckus
12/19/2024, 6:54 PM+ is the common operator for "adding", so which one is the correct one? (There isn't a single correct answer unfortunately).Ruckus
12/19/2024, 6:55 PM+Gasan
12/19/2024, 7:03 PM