如果我已经正确理解了您想要做什么,您可以使用列表中的distinct() 方法在此处提供帮助。它返回一个仅包含与原始列表不同的元素的列表,并保留出现的顺序。
val codes = listOf("or", "or", "or", "parks", "parks", "wa", "wa", "wa", "id")
val types = listOf("STATE", "NATIONAL", "STATE", "STATE")
// First, condense the "codes" list down to its distinct entries - which
// should make it the same size as "Types"
val condensedCodes = codes.distinct()
println(condensedCodes) // ["or","parks","wa","id"]
// Then create a map from code to type
val typeMap = condensedCodes.zip(types).toMap()
println(typeMap) // {or=STATE, parks=NATIONAL, wa=STATE, id=STATE}
// Then use that map to count the original codes list based on type
val numStates = codes.count { typeMap[it] == "STATE" }
println(numStates) // prints 7
// or if you want the list of states
val states = codes.filter { typeMap[it] == "STATE" }
println(states) // [or, or, or, wa, wa, wa, id]
// or if you want to transform the codes list to a list of types
val typeOfCodes = codes.map { typeMap[it] }
println(typeOfCodes) // [STATE, STATE, STATE, NATIONAL, NATIONAL, STATE, STATE, STATE, STATE]
如果同一组代码出现在列表中的多个位置,上述方法将不起作用。您不能再使用distinct,但仍然可以使用以下方法:
val codes = listOf("or", "or", "or", "parks", "parks", "wa", "wa", "id", "or", "or")
val types = listOf("STATE", "NATIONAL", "STATE", "STATE", "STATE")
val condensedCodes = codes.zipWithNext()
.filter { it.first != it.second }
.map { it.first } + codes.last()
这是如何工作的? zipWithNext() 创建一个这样的列表
[(or, or), (or, or), (or, parks), ...
然后它会被过滤到仅来自不匹配对的第一个元素,本质上是选择每组重复的最后一个元素。这样就漏掉了最后一组,所以我们在最后加上codes.last()。
["or", "or", "or", "parks", "parks", "wa", "wa", "wa", "id"]
^ ^ ^
[ "or", "parks", "wa" ] + "id"
如果您要在很多地方使用它,您可以为列表定义一个 extension function(Kotlin 的一个简洁功能)
fun <T> List<T>.condense() = when(isEmpty()) {
true -> listOf()
else -> zipWithNext().filter { it.first != it.second }.map { it.first } + last()
}
让你随便用
val condensedCodes = codes.condense()