Nate Jenson
Nate Jenson

Reputation: 2794

How can I remove duplicate objects with distinctBy from a list in Kotlin?

How can I use distinctBy on a list of custom objects to strip out the duplicates? I want to determine "uniqueness" by multiple properties of the object, but not all of them.

I was hoping something like this would work, but no luck:

val uniqueObjects = myObjectList.distinctBy { it.myField, it.myOtherField }

Edit: I'm curious how to use distinctBy with any number of properties, not just two like in my example above.

Upvotes: 53

Views: 39658

Answers (3)

You can create a triple:

myObjectList.distinctBy { Triple(it.firstField, it.secondField, it.thirdField) }

The distinctBy will use equality of Triple to determine uniqueness.

*I have implemented in this way, it provides most Unique list 👍

Upvotes: 0

Bob
Bob

Reputation: 13865

If you look at the implementation of the distinctBy, it just adds the value you pass in the lambda to a Set. And if the Set did not already contain the specified element, it adds the respective item of the original List to the new List and that new List is being returned as the result of distinctBy.

public inline fun <T, K> Iterable<T>.distinctBy(selector: (T) -> K): List<T> {
    val set = HashSet<K>()
    val list = ArrayList<T>()
    for (e in this) {
        val key = selector(e)
        if (set.add(key))
            list.add(e)
    }
    return list
}

So you can pass a composite object that holds the properties that you require to find the uniqueness.

data class Selector(val property1: String, val property2: String, ...)

And pass that Selector object inside the lambda:

myObjectList.distinctBy { Selector(it.property1, it.property2, ...) }

Upvotes: 18

nhaarman
nhaarman

Reputation: 100368

You can create a pair:

myObjectList.distinctBy { Pair(it.myField, it.myOtherField) }

The distinctBy will use equality of Pair to determine uniqueness.

Upvotes: 97

Related Questions