Reputation: 6746
How to remove duplicates from an Array<String?>
in Kotlin?
Upvotes: 179
Views: 110550
Reputation: 568
If you need to remove duplicates in-place use the following extension function:
fun <T : Comparable<T>> Array<T?>.distinctInPlace(): Int {
this.sortBy { it }
var placed = 1
var removed = 0
var i = 1
while (i < size) {
if (this[i] == this[i - 1])
removed++
else {
this[placed] = this[i]
placed++
}
i++
}
for (iter in size - removed..lastIndex)
this[iter] = null
return size - removed
}
This method will return the amount of unique elements in O(n log(n)) time. All of them will be sorted. Last for
loop is used to set all other elements to null
.
Note: if you had a null
element in the array, it will be placed at the 0 index - so you can distinguish whether you had any null
s or they were added after.
fun main() {
val arr = arrayOf("a", null, "b", null, "c", "ab", "ab")
arr.distinctInPlace() // returns 5, arr is now [null, "a", "ab", "b", "c", null, null]
val withoutNulls = arrayOf("a", "a", "aa", "aaa", "aa")
withoutNulls.distinctInPlace() // returns 3, arr is now ["a", "aa", "aaa"]
}
Upvotes: 1
Reputation: 147901
Use the distinct
extension function:
val a = arrayOf("a", "a", "b", "c", "c")
val b = a.distinct() // ["a", "b", "c"]
There's also distinctBy
function that allows one to specify how to distinguish the items:
val a = listOf("a", "b", "ab", "ba", "abc")
val b = a.distinctBy { it.length } // ["a", "ab", "abc"]
As @mfulton26 suggested, you can also use toSet
, toMutableSet
and, if you don't need the original ordering to be preserved, toHashSet
. These functions produce a Set
instead of a List
and should be a little bit more efficient than distinct
.
You may find useful:
Upvotes: 349