在 Kotlin 中是否有一种方便的方法来遍历数组,比如说 IntArray
,在这两个条件下以相反的顺序:
for
这样的元素的句柄。我能得到的最好的方法是添加一个扩展函数,但如果我不仅需要 IntArray
s,还需要为每种类型的数组完成此操作:
fun IntArray.forEachReversed(action: (Int) -> Unit): Unit {
for (i in indices.reversed()) action(this[i])
}
Kotlin 类库中有更好的方法吗?
答案 0 :(得分:1)
如果我不仅需要 IntArrays,还需要对每种类型的数组都这样做:
我认为这是不可避免的,因为 JVM 的工作方式。 JVM 上有单独的类来表示每个原始类型。但是,只有 8 个,所以应该不会太糟糕 ;-)
对于集合,有 asReversed()
函数,但它不适用于数组:
val original = mutableListOf('a', 'b', 'c', 'd', 'e')
val originalReadOnly = original as List<Char>
val reversed = originalReadOnly.asReversed()
println(original) // [a, b, c, d, e]
println(reversed) // [e, d, c, b, a]
// changing the original list affects its reversed view
original.add('f')
println(original) // [a, b, c, d, e, f]
println(reversed) // [f, e, d, c, b, a]
答案 1 :(得分:0)
为了回答您的问题,您的解决方案看起来不错,但是如果您针对原始 IntArray
、LongArray
、FloatArray
等,您不能使用通用解决方案,因为这些类是独立的并且唯一常见的是Iterator
,但是你不能在不复制的情况下以相反的顺序遍历iterator
(虽然ListIterator
支持反向迭代),但你能得到的最接近的是使用{{ 1}} 而不是像下面这样的特定数组
Array<T>
答案 2 :(得分:0)
正如@ajan.kali 所指出的,如果您需要原始数组,那么您无能为力。我想你必须处理数组,但如果不是这样,你应该更喜欢其他数据结构(更多信息 here) 回到你的问题,如果你可以使用泛型数组,你可能会声明你的迭代器以相反的顺序迭代:
class ReverseIterator<T>(val it: Iterable<T>) : Iterator<T> {
private var index = it.count() - 1
override fun hasNext() = index >= 0
override fun next(): T = try { it.elementAt(index--) } catch (e:
IndexOutOfBoundsException) { index -= 1; throw
NoSuchElementException(e.message) }
}
那么你的扩展函数就会变成:
fun <T> Iterable<T>.forEachReversed(action: (T) -> Unit) {
for(elem in ReverseIterator(this)) {
action(elem)
}
}
然后给定一个数组,你可以这样调用它:
intArrayOf(1, 2, 3).asIterable().forEachReversed {
println(it)
}
对此不是特别满意,但是对于数组,除了尝试避免它们之外,您无能为力。