I have a `var list: List<Item>`, what would ...
# getting-started
m
I have a
var list: List<Item>
, what would be an idiomatic way of replacing one item of this list? It’s not a MutableList, so I need a way to generate a new copy of this list, with a single element replaced.
I could do something like
list = list.take(indexOfItem) + newItem + list.drop(indexOfItem + 1)
but it feels like it could be simpler.
a
Does order matter? Should the new item have the same index as the old item?
m
It does.
Hmm, maybe
Copy code
items = items.map { if (it == oldItem) newItem else it }
a
you beat me to it, I was going to suggest exactly that :)
you might want to have a
require(oldItem in items)
check
👍 1
if you wanted to make this list more reusable you could create a value class that has a private mutable list that implements
List<T>
via delegation
m
It’s a
var items by remember { mutableStateOf(listOf(originalContents...)) }
that I need mutate in response to click handlers in Compose. Normally the handlers would go up higher but in this case it’s a Compose @Preview.
j
As a side note, you could also use persistent collections if you use this pattern often: https://github.com/Kotlin/kotlinx.collections.immutable They offer the
mutate
extension which simplifies this kind of operation
I think Compose already uses this library behind the scenes so it shouldn't bring more dependencies to your project since it seems you're already using Compose
c
In case you're not aware, you can also use
val items = remember { mutableStateListOf(originalContents) }
then use the regular mutable
replace
. Compose will still recompose correctly.
☝️ 1
m
What’s the
replace
method? I’m not seeing it. There is
replaceAll
which looks like it would solve it, but sadly it requires API level 24 on Android.
e
I don't think Compose uses kotlinx.collections.immutable directly, but the compiler recognizes it as immutable
Copy code
val newList = buildList(list.size) {
    addAll(list)
    set(indexOfItem, newItem)
}
c
@Marcin Wisniowski Sorry, it's called
set
, not
replace
m
That does work quite nicely, thanks.