nkiesel
03/15/2021, 5:11 PMfun <T> List<T>.replaceOrAdd1(item: T, predicate: (T) -> Boolean): List<T> { ... }
fun <T> List<T>.replaceOrAdd2(item: T, predicate: (T) -> Boolean): List<T> { ... }
data class Person(val name: String, val age: Int, val email: String, val address: String = "")
val listOfProposals = listOf(
fun(list: List<Person>, person: Person, predicate: (Person) -> Boolean) = list.replaceOrAdd1(person, predicate),
fun(list: List<Person>, person: Person, predicate: (Person) -> Boolean) = list.replaceOrAdd2(person, predicate),
)
// <https://pl.kotl.in/GvbQWnFEq> is the link to the working example
Nir
03/15/2021, 5:20 PMval functions = listOf(
List<Person>::replaceOrAdd1,
List<Person>::replaceOrAdd2,
List<Person>::replaceOrAdd3,
List<Person>::replaceOrAdd4,
)
Nir
03/15/2021, 5:21 PMNir
03/15/2021, 5:21 PMNir
03/15/2021, 5:22 PMnkiesel
03/15/2021, 5:23 PMYoussef Shoaib [MOD]
03/15/2021, 5:23 PMNir
03/15/2021, 5:23 PMNir
03/15/2021, 5:23 PMNir
03/15/2021, 5:23 PMNir
03/15/2021, 5:23 PMinline fun <reified T> functions() = listOf(
List<T>::replaceOrAdd1,
List<T>::replaceOrAdd2,
List<T>::replaceOrAdd3,
List<T>::replaceOrAdd4,
)
Youssef Shoaib [MOD]
03/15/2021, 5:24 PMnkiesel
03/15/2021, 5:24 PMYoussef Shoaib [MOD]
03/15/2021, 5:25 PMNir
03/15/2021, 5:25 PMnkiesel
03/15/2021, 5:26 PMnkiesel
03/15/2021, 5:32 PMinline fun <reified T> functions()
approachnkiesel
03/15/2021, 5:34 PMNir
03/15/2021, 5:34 PMNir
03/15/2021, 5:36 PMNir
03/15/2021, 5:36 PMNir
03/15/2021, 5:37 PMnkiesel
03/15/2021, 5:37 PMfun main()
wrapper so that I can execute the code. But that seems to have side effects. I just started using these scratch files and perhaps do not yet underdtand their limitationsNir
03/15/2021, 5:38 PMNir
03/15/2021, 5:39 PMNir
03/15/2021, 5:39 PMNir
03/15/2021, 5:39 PMnkiesel
03/15/2021, 5:39 PMnotReplaced
in the loop it would perform a "replaceAll" instead of "replaceFirst"Nir
03/15/2021, 5:39 PMNir
03/15/2021, 5:40 PMNir
03/15/2021, 5:40 PMNir
03/15/2021, 5:40 PMnkiesel
03/15/2021, 5:41 PMNir
03/15/2021, 5:41 PMnkiesel
03/15/2021, 5:41 PMNir
03/15/2021, 5:41 PMNir
03/15/2021, 5:41 PMNir
03/15/2021, 5:41 PMnkiesel
03/15/2021, 5:42 PMNir
03/15/2021, 5:43 PMNir
03/15/2021, 5:43 PMNir
03/15/2021, 5:43 PMnkiesel
03/15/2021, 5:43 PMNir
03/15/2021, 5:43 PMNir
03/15/2021, 5:44 PMnkiesel
03/15/2021, 5:44 PMNir
03/15/2021, 5:44 PMNir
03/15/2021, 5:44 PMnkiesel
03/15/2021, 5:45 PMNir
03/15/2021, 5:45 PMNir
03/15/2021, 5:45 PMNir
03/15/2021, 5:46 PMephemient
03/15/2021, 5:46 PMbuildList
nkiesel
03/15/2021, 5:46 PMnkiesel
03/15/2021, 5:47 PMephemient
03/15/2021, 5:49 PMfun <T> List<T>.replaceOrAdd(replacement: T, predicate: (T) -> Boolean): List<T> = buildList {
val replaced = false
for (item in this@replaceOrAdd) {
if (!replaced && predicate(item)) {
add(replacement)
replaced = true
} else {
add(item)
}
}
if (!replaced) {
add(replacement)
}
}
ephemient
03/15/2021, 5:49 PMnkiesel
03/15/2021, 5:51 PM!
in the last if... never mind, you just correctedNir
03/15/2021, 5:52 PMephemient
03/15/2021, 5:52 PMfun <T> List<T>.replaceOrAdd(replacement: T, predicate: (T) -> Boolean): List<T> = buildList {
val iterator = this@replaceOrAdd.iterator()
for (item in iterator) {
if (predicate(item)) break
add(item)
}
add(replacement)
for (item in iterator) add(item)
}
nkiesel
03/15/2021, 5:53 PMnkiesel
03/15/2021, 5:54 PMNir
03/15/2021, 5:54 PMreplaceAt
functionNir
03/15/2021, 5:54 PMList<T>.replaceAt(index: Int, value: T): List<T>
Nir
03/15/2021, 5:55 PMnkiesel
03/15/2021, 5:55 PMNir
03/15/2021, 5:55 PMreplaceOrAdd
function is arguably quite a bit more natural (and efficient) on a mutable list to start withJoel
03/15/2021, 6:32 PMnkiesel
03/15/2021, 6:33 PMJoel
03/15/2021, 6:37 PMfun <T> List<T>.replaceOrAdd(item: T, predicate: (T) -> Boolean): List<T> {
val left = takeWhile { !predicate(it) }
return left + item + (this - left).drop(1)
}
I submit my readable but untested slightly suboptimal version.Nir
03/15/2021, 6:39 PMephemient
03/15/2021, 6:40 PMtakeWhile { !predicate(it) } + item + dropWhile { !predicate(it) }.drop(1)
Nir
03/15/2021, 6:40 PMJoel
03/15/2021, 6:41 PMbuildList
version you proposed.Nir
03/15/2021, 6:41 PMnkiesel
03/15/2021, 6:43 PMtakeWhile
versions 3 times now and still can't confirm their correctness in my head. I e.g. wonder if this really implements the "only replace the first match" condition (which actually was never really specified, but all the other implementations do that)ephemient
03/15/2021, 6:44 PMJoel
03/15/2021, 6:44 PMnkiesel
03/15/2021, 6:44 PMephemient
03/15/2021, 6:45 PMNir
03/15/2021, 6:46 PMNir
03/15/2021, 6:46 PMJoel
03/15/2021, 6:46 PMNir
03/15/2021, 6:47 PMJoel
03/15/2021, 6:47 PMmutableListOf(1,2,3,2,1).remove(2)
ephemient
03/15/2021, 6:47 PMJoel
03/15/2021, 6:48 PMJoel
03/15/2021, 6:49 PMephemient
03/15/2021, 6:51 PMfun <T> Iterable<T>.minus(elements: Iterable<T>) {
val remainingElementsToRemove = elements.toMutableSet()
return this.filterNot { remainingElementsToRemove.remove(it) }
}
and it would have the "remove only once" behaviorephemient
03/15/2021, 6:51 PMephemient
03/15/2021, 6:51 PMephemient
03/15/2021, 6:52 PMJoel
03/15/2021, 6:53 PMJoel
03/15/2021, 6:54 PMephemient
03/15/2021, 6:54 PMlistOf(1, 2, 3, 1) - 1 == listOf(2, 3, 1); listOf(1, 2, 3, 1) - listOf(1) == listOf(2, 3)
ephemient
03/15/2021, 6:54 PMJoel
03/15/2021, 6:54 PMephemient
03/15/2021, 6:54 PMJoel
03/15/2021, 6:55 PMlistOf(2,3,1)
ephemient
03/15/2021, 6:55 PMephemient
03/15/2021, 6:55 PMJoel
03/15/2021, 6:55 PMremainingElementsToRemove.remove(it)
only removes onceJoel
03/15/2021, 6:55 PMephemient
03/15/2021, 6:55 PMephemient
03/15/2021, 6:56 PMlistOf(1, 1, 1) - listOf(1, 1) == listOf(1)
, well mine doesn't do that. you'd need a multiset (or map) to keep track.ephemient
03/15/2021, 6:57 PMWell, that assumes thatonly removes onceremainingElementsToRemove.remove(it)
And breaks early if it finds the elementI don't understand what you mean by that
Nir
03/15/2021, 6:57 PMNir
03/15/2021, 6:57 PMephemient
03/15/2021, 6:58 PMelements
argument, not this
Nir
03/15/2021, 6:58 PMephemient
03/15/2021, 6:58 PMin/.contains
query each time, to the same effect (except for runtime)Nir
03/15/2021, 6:59 PMephemient
03/15/2021, 7:00 PMJoel
03/15/2021, 7:03 PMephemient
03/15/2021, 7:06 PMephemient
03/15/2021, 7:06 PMephemient
03/15/2021, 7:07 PMJoel
03/15/2021, 7:07 PMlistOf(1,1,1) - listOf(1)
, emptyList()
and listOf(1,1)
are both valid answersJoel
03/15/2021, 7:08 PMephemient
03/15/2021, 7:09 PMJoel
03/15/2021, 7:09 PMephemient
03/15/2021, 7:10 PM.removeAll()
isn't as well documented on the Kotlin side... but it behaves just like Java's .removeAll()
so shrug just go read the original Javadoc I guessNir
03/15/2021, 7:25 PM