:question: What's the cleanest way to test if all ...
# getting-started
v
What's the cleanest way to test if all elements in a list are distinct? The best I could come up with was
list.size == list.distinct().size
, which is efficient, but ugly
☝️ 1
h
Unless the list in question is huge this is the best solution. I don't think it's that ugly, either – just put it in an extension:
Copy code
fun Collection<*> allDistinct(): Boolean = this.size == this.distinct().size
s
distinct converts it to a mutableset then toList()
which should be fine, but if the list is large then you false-fast when you find the first duplicate
Copy code
fun <T> List<T>.isDistinct() = this.fold(mutableMapOf<T,Int>()) { acc, i ->
    acc.also {
        it[i] = ((it[i] ?: 0) + 1).also { count ->
            if(count > 1) {
                return false
            }
        }
    }
}.let { true }
you would have to benchmark to see if there was any real performance gains to be had
if its sorted there much quicker ways as you only have to compare the previous element
m
Could also go for a procedural approach that stops immediately when it finds a duplicate:
Copy code
fun <T> List<T>.isDistinct(): Boolean {
    val mutSet = mutableSetOf<T>()
    for (elem in this) {
        if (elem in mutSet) {
            return false
        }
        mutSet.add(elem)
    }
    return true
}
p
Or just
Copy code
fun <T> List<T>.isDistinct(): Boolean {
    val mutSet = mutableSetOf<T>()
    return all { mutSet.add(it) }
}
3
v
Nice optimizations! Feels like such a method could be in the stdlib. Do you think I should open an issue?
Here is the issue https://youtrack.jetbrains.com/issue/KT-30270 @Pavlo Liapota I hope you don't mind I posted your code there
👍 1