假设我正在尝试实现一些功能:
private fun List<Int>.padWithIndices(newLength: Int): List<Int>
它获取一个列表并返回带有一些附加值的列表,其中对于每个新值,this [i] = i。
Kotlin为我们提供了很多不错的方法来附加到列表,连接两个不同的列表,创建可变列表等。如此之多,我不知道在这种情况下哪个是最好的,而且我不知道是否有任何方法隐藏的陷阱。这是我最初的基于for的解决方案,是否有更有效/惯用的解决方案?
fun List<Int>.padWithIndices(newLength: Int): List<Int> {
var newList = this
for (x in size until newLength) {
newList += x
}
return newList
}
最佳答案
尽管您的解决方案可读性强,但它会在List<Int>
-loop的每次迭代中复制原始for
的所有项目,因为+=
上的var newList: List<Int>
每次都会创建一个新列表。最坏情况的计算复杂度为O(n²),可以提高到O(n)。
对于这种特殊情况,当您只想将连续范围添加到列表中时,像这样的单行函数将起作用:
fun List<Int>.padWithIndices(newLength: Int): List<Int> =
plus(size until newLength)
(runnable sample)
它在接收者列表上调用
plus
函数,生成一个新列表,其中附加了参数中的项目。您也可以将
plus
称为operator +
,将其替换为this + (size until newLength)
。对于使用更复杂的逻辑来计算要添加到列表的项目的用例,可以使用
List(n) { ... }
factory function,它接受提供列表项的lambda,从而确保每个列表项仅被计算一次:fun List<Int>.padWithIndices(newLength: Int): List<Int> =
List(newLength) { index -> getOrNull(index) ?: index }
(runnable sample)
函数
getOrNull(index)
返回指定索引处的项目;如果索引超出范围,则返回null
。后者由?: index
处理。或者,重写您的解决方案,并在函数实现中使用可变列表,在其中添加各项,然后将其作为只读
List<Int>
返回:fun List<Int>.padWithIndices(newLength: Int): List<Int> =
toMutableList().apply {
addAll(size until newLength)
}
(runnable sample)
关于kotlin - Kotlin中惯用的方式来转换/附加到列表?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56758351/