如何从Kotlin中的列表中删除带有distinctBy的重复对象?

Nat*_*son 18 kotlin

如何distinctBy在自定义对象列表中使用以删除重复项?我想通过对象的多个属性来确定"唯一性",但不是全部.

我希望这样的东西可行,但没有运气:

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

编辑:我很好奇如何使用distinctBy任意数量的属性,而不仅仅是像我上面的例子中的两个.

nha*_*man 32

你可以创建一对:

myObjectList.distinctBy { Pair(it.myField, it.myOtherField) }
Run Code Online (Sandbox Code Playgroud)

distinctBy会用平等的Pair,以确定唯一性.

  • 要比较更多的值,可以使用`.distinctBy {listOf(...)}` (6认同)
  • 或者甚至只是`it.myField to it.myOtherField`. (3认同)
  • 还有另一种非惯用的方式-覆盖“等于”和“哈希码”,仅比较确定重复项所需的几个字段,然后使用简单的“ distinct()” (2认同)

Bob*_*Bob 11

如果你看一下它的实现distinctBy,它只是将你在lambda中传递的值添加到Set.如果Set它还没有包含指定的元素,它会将原始的相应项添加List到new中,List并且将List返回new 作为结果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
}
Run Code Online (Sandbox Code Playgroud)

因此,您可以传递一个复合对象,该对象包含查找唯一性所需的属性.

data class Selector(val property1: String, val property2: String, ...)
Run Code Online (Sandbox Code Playgroud)

Selector在lambda中传递该对象:

myObjectList.distinctBy { Selector(it.property1, it.property2, ...) }
Run Code Online (Sandbox Code Playgroud)