我正在学习Kotlin
。帮我理解一下。正如我所知,distinct
只返回唯一的值。因此,如果我们有两次或两次以上相同的值,它将只返回一次。如果我错了,请纠正我。但是这个distinctBy
方法是什么呢?据我所知,它必须根据我的谓词返回唯一的值。
我有这样的代码:
fun main() {
val myList = listOf(5, 2, 9, 12, 5, 2)
myList.distinctBy { it > 10 }.forEach { println(it) }
所以它必须返回12imho,但我得到了一个输出:5,12。但为什么呢?
distinctBy
采用选择器,而不是谓词。它通常用于对象,在这些对象中,您需要基于特定字段的区别。一个例子:
fun main() {
val list = listOf(
Pojo(1, "abc"),
Pojo(2, "xyz"),
Pojo(1, "hello"),
Pojo(1, "world")
)
list.distinctBy { it.fizz }.forEach { println(it) }
}
data class Pojo(
val fizz: Int,
val buzz: String
)
这将在fizz
属性上返回一个distinct。
Pojo(fizz=1, buzz=abc)
Pojo(fizz=2, buzz=xyz)
如果你想使用谓词,你应该使用类似filter
的东西。
val myList = listOf(5, 2, 9, 12, 5, 2, 13, 12)
myList.filter { it > 10 }.forEach { println(it) }
这将打印:
12
13
12
正如您所看到的,filter
不会给您一个唯一的列表。您可以通过在筛选器之前调用列表中的toSet()
来实现这一点(在筛选器之后它仍然是List
(。或者在过滤器之后调用distinct()
。distinct()
实际上只会创建一个Set
,并将其重新打开为List
,所以我建议在过滤器之前只使用toSet()
。
distinctBy
正在使用选择器对列表中的对象进行区分。这很少用于基元。在您的情况下,为键true和false创建两个键映射,并且只映射前两个值。
我想你想过滤掉所有大于10的数字,你必须使用.filter { it > 10 }
。
返回仅包含给定集合中元素的列表具有由给定的[selector]函数返回的不同键。
您将获得5 12
作为输出,因为您所做的操作类似于:
val myList = listOf(5, 2, 9, 12, 5, 2)
val set = HashSet<Boolean>()
val list = ArrayList<Int>()
for (e in myList) {
if (set.add(e>10)) {
list.add(e)
}
}
list.forEach { println(it) }