Python有一个切片操作符,我想在Kotlin中使用它。
我想在Kotlin中使用以下代码
val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
println(
list[5]
)
println(
list[2, 5].joinToString()
)
println(
list[2, 10, 2].joinToString()
)
val mutableList = mutableListOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
mutableList[2, 10, 2] = listOf(1, 2, 3, 4)
println(
mutableList.joinToString()
)
输出以下内容:
6
3, 4, 5
3, 5, 7, 9
1, 2, 1, 4, 2, 6, 3, 8, 4, 10
但它不起作用!
答案 0 :(得分:2)
这可以使用扩展函数和运算符重载来完成。以下代码将解决您提供的问题。通过一些调整,它将处理Python提供的所有其他选项。
operator fun <T : Any> Iterable<T>.get(start: Int, end: Int, step: Int = 1): Iterable<T> {
check(start < end)
check(step > 0)
val iterator = iterator()
var s = 0
return generateSequence {
while (s < start && iterator.hasNext()) {
iterator.next()
s++
}
if (iterator.hasNext()) {
if (s < end) {
val value = iterator.next()
repeat(step - 1) { s++; if (iterator.hasNext()) iterator.next() }
s++
value
} else {
null
}
} else {
null
}
}.asIterable<T>()
}
operator fun <T : Any> MutableList<T>.set(start: Int, end: Int, step: Int = 1, newElts: Iterable<T>) {
check(start < end)
check(step > 0)
val iterator = iterator()
val newIterator = newElts.iterator()
var s = 0
while (s < start && iterator.hasNext()) {
iterator.next()
s++
}
while (iterator.hasNext()) {
if (s < end) {
if (newIterator.hasNext()) {
this[s] = newIterator.next()
iterator.next()
repeat(step - 1) {
s++;
if (iterator.hasNext())
iterator.next()
else
return
}
s++
} else
return
}
}
}
gladed上的{p> reddit提出了另一个不使用Python语法但我非常喜欢的解决方案。
operator fun <T: Any> Iterable<T>.get(range: IntProgression) = asSequence().run {
range.mapNotNull { index -> elementAtOrNull(index) }
}
operator fun <T: Any> MutableList<T>.set(range: ClosedRange<Int>, from: Iterable<T>) {
for (i in range.start..minOf(range.endInclusive, size - 1)) removeAt(range.start)
addAll(range.start, from.toList())
}
@Test
fun slice() {
val list = mutableListOf(5, 6, 7, 8, 9, 10)
assertEquals(listOf(7, 8, 9), list[2..4])
assertEquals(listOf(10, 8), list[5 downTo 2 step 2])
list[2..4] = listOf(77)
assertEquals(listOf(5, 6, 77, 10), list)
list[0..10] = listOf(1, 2, 3)
assertEquals(listOf(1, 2, 3), list)
}