如何使用Kotlin的minOf函数查找Pair中值最小的列表项索引?
如何用Kotlin的minOf函数找到Pair集合中值最小项的索引?
我需要从生成的包含(索引,计算值)的Pair集合中,找到第二个元素(值)最小的项的索引,希望使用minOf函数实现。以下是我尝试的两段代码:
第一段无法编译的代码
val index = listOf("abc", "def", "ghi", "jkl", "mno") .mapIndexed { index, v -> var t = 0 var p = 0 for (s in v) { t += ("deh".get(p++).toInt() - s.toInt()).absoluteValue } Pair(index, v) } .minOf { val iterator = iterator<Pair<Int, String>>(it) if (!iterator.hasNext()) throw NoSuchElementException() var minValue = iterator.next().second while (iterator.hasNext()) { val v = selector(iterator.next()) minValue = minOf(minValue, v) } return minValue }
第二段可行但想替换为minOf的代码
val index = listOf("abc", "def", "ghi", "jkl", "jad", "jaa", "mno") .mapIndexed { index, v -> var t = 0 var p = 0 for (s in v) { t += ("jac".get(p++).toInt() - s.toInt()).absoluteValue } Pair(index, t) }.toSortedSet(compareBy { it.second }) .first()
问题分析
第一段代码完全误解了minOf的用法:这个函数本身就是用来遍历集合、根据规则获取最小值的工具,不需要你手动实现迭代逻辑。你写的内部遍历代码属于重复造轮子,还存在语法错误(比如错误创建迭代器、未定义的selector函数),因此无法编译。
正确实现方式
方式1:用minByOrNull找目标Pair(推荐,更贴合需求)
虽然你指定要用minOf,但minByOrNull更适合你的场景——它直接返回集合中使指定selector值最小的元素,后续只需取出索引即可:
val targetPair = listOf("abc", "def", "ghi", "jkl", "jad", "jaa", "mno") .mapIndexed { index, v -> var t = 0 var p = 0 for (s in v) { t += ("jac".get(p++).toInt() - s.toInt()).absoluteValue } Pair(index, t) } .minByOrNull { it.second } // 获取second最小的Pair val index = targetPair?.first ?: -1 // 取出索引,空集合时返回-1(可按需调整默认值)
方式2:用minOf先取最小值再找索引
如果一定要用minOf,可以先获取最小的second值,再遍历集合找到对应的索引(若有多个相同最小值,会返回第一个出现的索引):
val pairs = listOf("abc", "def", "ghi", "jkl", "jad", "jaa", "mno") .mapIndexed { index, v -> var t = 0 var p = 0 for (s in v) { t += ("jac".get(p++).toInt() - s.toInt()).absoluteValue } Pair(index, t) } val minValue = pairs.minOf { it.second } // 用minOf获取最小的计算值 val index = pairs.first { it.second == minValue }.first // 找到对应Pair并取出索引
补充说明
你第二段用toSortedSet的代码逻辑是正确的,但效率不如上述方法:排序的时间复杂度为O(n log n),而minByOrNull和minOf的遍历都是O(n),在数据量较大时差异会更明显。
内容的提问来源于stack exchange,提问作者Johann
相关产品推荐
相关产品推荐

