如何用乘法或除法迭代 for 循环? [科特林]
How do you iterate a for loop with multiplication or division? [Kotlin]
如何在 Kotlin 中编写迭代步骤以进行乘法、除法或具有一些自定义迭代函数?我知道我可以改用 while 循环,但是 for 循环在范围上似乎比在其他语言中更受限制。这是设计使然吗?
大多数其他语言的可用内容:
for(let i = 1; i <= 10; i *= 2) // [JavaScript]
for i := 1; i <= 10; i*=2 // [Golang]
我想用 Kotlin(或类似的东西)做的事情:
for(i in 1..10 step 2 * i) // [Kotlin]
如果我们可以在 for 循环体本身中引用迭代器会很容易,但是上面会导致 'Unresolved reference' 错误,因为在迭代步骤中无法引用 i
。
您可以构造一个 Sequence
然后迭代它。
fun myProgression(from: Int, toInclusive: Int? = null, transform: (Int) -> Int = { it + 1 }) = when {
toInclusive == null -> generateSequence(from, transform) //infinite sequence
toInclusive < from -> emptySequence()
else -> generateSequence(from) {
val next = transform(it)
if (next > toInclusive) null else next
}
}
用法:
//1, 2, 4, 8
for (i in myProgression(1, 10) { it * 2 }) {
println(i)
}
//1, 2, 4, 8, 16, 32, 64, 128, 256, 512
myProgression(1) { it * 2 }.take(10).forEach { println(it) }
//simple loop in 1..10 range
for (i in myProgression(1, 10)) {
println(i)
}
是的,很遗憾 Kotlin 设计者决定不支持 C 风格的 for
循环,但您可以使用扩展函数做一些技巧。
声明中缀函数
// for increasing rangeTo (..)
infix fun IntRange.step(next: (Int) -> Int) =
generateSequence(first, next).takeWhile { if (first < last) it <= last else it >= last }
// for decreasing downTo
infix fun IntProgression.step(next: (Int) -> Int) = (first..last).step(next)
并像下面这样使用它
for (i in 1..10 step { it * 2 }) {
println(i)
}
输出
1
2
4
8
和
for (i in 16 downTo 1 step { it / 2 }) {
println(i)
}
输出
16
8
4
2
1
没错,Kotlin 中的 for
循环受设计限制。之所以决定这样做,是因为循环标题中的复杂条件是 error-prone。我建议针对您的特定情况使用 while
循环。
如何在 Kotlin 中编写迭代步骤以进行乘法、除法或具有一些自定义迭代函数?我知道我可以改用 while 循环,但是 for 循环在范围上似乎比在其他语言中更受限制。这是设计使然吗?
大多数其他语言的可用内容:
for(let i = 1; i <= 10; i *= 2) // [JavaScript]
for i := 1; i <= 10; i*=2 // [Golang]
我想用 Kotlin(或类似的东西)做的事情:
for(i in 1..10 step 2 * i) // [Kotlin]
如果我们可以在 for 循环体本身中引用迭代器会很容易,但是上面会导致 'Unresolved reference' 错误,因为在迭代步骤中无法引用 i
。
您可以构造一个 Sequence
然后迭代它。
fun myProgression(from: Int, toInclusive: Int? = null, transform: (Int) -> Int = { it + 1 }) = when {
toInclusive == null -> generateSequence(from, transform) //infinite sequence
toInclusive < from -> emptySequence()
else -> generateSequence(from) {
val next = transform(it)
if (next > toInclusive) null else next
}
}
用法:
//1, 2, 4, 8
for (i in myProgression(1, 10) { it * 2 }) {
println(i)
}
//1, 2, 4, 8, 16, 32, 64, 128, 256, 512
myProgression(1) { it * 2 }.take(10).forEach { println(it) }
//simple loop in 1..10 range
for (i in myProgression(1, 10)) {
println(i)
}
是的,很遗憾 Kotlin 设计者决定不支持 C 风格的 for
循环,但您可以使用扩展函数做一些技巧。
声明中缀函数
// for increasing rangeTo (..)
infix fun IntRange.step(next: (Int) -> Int) =
generateSequence(first, next).takeWhile { if (first < last) it <= last else it >= last }
// for decreasing downTo
infix fun IntProgression.step(next: (Int) -> Int) = (first..last).step(next)
并像下面这样使用它
for (i in 1..10 step { it * 2 }) {
println(i)
}
输出
1
2
4
8
和
for (i in 16 downTo 1 step { it / 2 }) {
println(i)
}
输出
16
8
4
2
1
没错,Kotlin 中的 for
循环受设计限制。之所以决定这样做,是因为循环标题中的复杂条件是 error-prone。我建议针对您的特定情况使用 while
循环。