Hey, does anybody know a cool std lib function or ...
# announcements
m
Hey, does anybody know a cool std lib function or combination of functions that would achieve the following?
Copy code
val x = listOf("a", "a", "b").function(listOf("a", "c"))
where
Copy code
x == listOf("a", "b")
When using
Copy code
listOf("a", "a", "b") - listOf("a", "c")
I get
Copy code
x == list("b")
but I want to have one
a
in there. I know that I could do:
Copy code
var a = listOf("a", "a", "b")
val b = listOf("a", "c")
b.forEach {
    a = a - it
}
But I don’t really like the
forEach
and
var
in that solution.
e
You could use
fold
and
minus
with a single element (
a.minus(b)
would remove all occurences of "a"):
Copy code
val a = listOf("a", "a", "b")
val b = listOf("a", "c")
val x = b.fold(a) { result, element ->
    result.minus(element)
}
println(x) // [a, b]
Or just
-
instead of
.minus()
. I didn't know that worked on lists. 😮
k
That is still quite an expensive operation if the lists were larger.
👍 1
m
@Kroppeb Yeah I know that it’s expensive, but I need that anyways. @Eivind Nilsbakken Thanks! That looks good.
e
That's a good point. It should be faster to turn the exclusion list into a map of string counts and use that for lookup in a single pass over
a
.
Copy code
val a = listOf("a", "a", "b")
val b = listOf("a", "c")
val c = b.groupingBy { it }.eachCount() as MutableMap<String, Int>

val x = a.filter {value ->
    c[value] = (c[value] ?: 0) - 1
    c[value]!! < 0
}
println(x) // [a, b]
I haven't benchmarked it though, and there are probably faster and more elegant solutions. The second approach is considerably faster for large sizes of
a
. Eg. with
a.size == 10000
and
b.size == 5000
they take 376 vs 7 millis to execute. The first approach is faster than the second though, which isn't surprising, since it saves time on not creating and using the lookup map. (https://pl.kotl.in/B0TnYmQ3Y)
👏 1