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 AMnull
Gasan
12/19/2024, 11:34 AMnull
Jaap 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 null
Julien 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