我有多个具有相同键的对象的数组,其他对象具有空值,我希望使用 distinctBy 删除重复项并获取值具有最长字符串的对象。
data class ObjA(val key: String, val value: String)
fun test() {
val listOfA = mutableListOf(
ObjA("one", ""), //This will be taken in distinctBy.
ObjA("one", "o"),
ObjA("one", "on"),
ObjA("one", "one"), //This will be ignored in distinctBy. I WANT THIS ONE.
ObjA("two", ""), //This will be returned in distinctBy
ObjA("two", "2"),
ObjA("two", "two"), //But I want this.
ObjA("three", "3"),
ObjA("four", "4"),
ObjA("five", "five")
)
val listOfAWithNoDuplicates = listOfA.distinctBy { it.key }
for (o in listOfAWithNoDuplicates) {
println("key: ${o.key}, value: ${o.value}")
}
}
Run Code Online (Sandbox Code Playgroud)
输出
key: one, value:
key: two, value:
key: three, value: 3
key: four, value: 4
key: five, value: five
Run Code Online (Sandbox Code Playgroud)
如何使这项工作。任何帮助将不胜感激。
由于distinctBy只是根据您的选择器(并按照列表的顺序)返回不同的键,因此您最终会得到唯一的键,但还没有您想要的值。
对于那个特定的用例,我可能会预先排序,然后是distinctBy
listOfA.sortedByDescending { it.value.length }
.distinctBy { it.key }
Run Code Online (Sandbox Code Playgroud)
这会在 at 处创建一个新列表,sortedByDescending或者您只是预先对当前列表进行排序 ( sortByDescending) 并distinctBy稍后应用,例如:
listOfA.sortByDescending { it.value.length }
listOfA.distinctBy { it.key }
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您都会得到一个List<ObjA>具有预期值的新值。
我还想到了其他几种变体。所有这些变体都会将结果放入一个Map<String, ObjA>键实际上是唯一的ObjA.key. .values如果您对 key/ ObjA-mapping不感兴趣,您可能想直接调用。
使用groupingBy和的变体reduce:
listOfA.groupingBy { it.key }
.reduce { _, acc, e->
maxOf(e, acc, compareBy { it.value.length })
}
Run Code Online (Sandbox Code Playgroud)使用普通forEach/for并填充自己的变体Map:
val map = mutableMapOf<String, ObjA>()
listOfA.forEach {
map.merge(it.key, it) { t, u ->
maxOf(t, u, compareBy { it.value.length })
}
}
Run Code Online (Sandbox Code Playgroud)使用foldand 的变体merge(与之前的非常相似......只是使用fold而不是for/ forEach):
listOfA.fold(mutableMapOf<String, ObjA>()) { acc, objA ->
acc.apply {
merge(objA.key, objA) { t, u ->
maxOf(t, u, compareBy { it.value.length })
}
}
}
Run Code Online (Sandbox Code Playgroud)变体使用groupBy后跟mapValues(但您实际上是在创建 1 个您立即丢弃的地图):
listOfA.groupBy { it.key } // the map created at this step is discarded and all the values are remapped in the next step
.mapValues { (_, values) ->
values.maxBy { it.value.length }!!
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
3351 次 |
| 最近记录: |