Kotlin:以相反的顺序遍历数组

时间:2021-02-09 06:49:40

标签: kotlin

在 Kotlin 中是否有一种方便的方法来遍历数组,比如说 IntArray,在这两个条件下以相反的顺序:

  • 不要创建数组的额外反向副本。
  • 我需要一个像 Java 增强的 for 这样的元素的句柄。

我能得到的最好的方法是添加一个扩展函数,但如果我不仅需要 IntArray s,还需要为每种类型的数组完成此操作:

fun IntArray.forEachReversed(action: (Int) -> Unit): Unit {
    for (i in indices.reversed()) action(this[i])
}

Kotlin 类库中有更好的方法吗?

3 个答案:

答案 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)

为了回答您的问题,您的解决方案看起来不错,但是如果您针对原始 IntArrayLongArrayFloatArray 等,您不能使用通用解决方案,因为这些类是独立的并且唯一常见的是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)
}

对此不是特别满意,但是对于数组,除了尝试避免它们之外,您无能为力。