2017-02-23 6 views
2

配列の一部を後方に反復する必要があります。私はそれがKotlinレイジースライスアレイ

for (b in buf.sliceArray(0 until bufLimit).reversedArray()) {} 

のように、より分かります。しかしsliceArrayreversedArray両方が怠け者ではないとして、「機能的」ということをしたいと思います。怠惰なバージョンがありますか、おそらく私に戻ってください

for (bIdx in bufLimit - 1 downTo 0) { 
    val b = buf[bIdx] 
} 

これはもっと混乱し、冗長ですか?

+0

何を? 'buf.take(bufLimit).reversed()。forEach {...}' – marstran

+0

@marstran 'ByteArray.take'もレイジーではなく、' ArrayList'を作成します。 –

答えて

1

、その後、あなたはそれを逆にして、Sequenceに変換することができます:

val buf: List = listOf(1, 2, 3, 4, 5) 
val bufLimit = 3 

for (b in buf.asReversed().asSequence().drop(buf.size - bufLimit)) { 
    println(b) 
} 

機能付きas接頭辞はオブジェクトをコピーせずにラップするだけなので、上のコードではbufのコンテンツはコピーされません。

ArrayListを使用する場合は、Arrayと比べてパフォーマンスが低下しないように注意してください。

しかし、この解決策は、いくつかのイテレータを伴わないので、それはあなたが質問に示唆されているインデックスコードよりもやや少ない効率的です。これについて

for (bIdx in bufLimit - 1 downTo 0) { 
    val b = buf[bIdx] 
} 
1

特定のユースケースを処理する拡張機能を作成することをお勧めします。例えば:

/** 
* Performs the given [action] on each element at the specified [indices]. 
*/ 
inline fun ByteArray.forEachAt(indices: Iterable<Int>, action: (Byte) -> Unit): Unit { 
    indices.forEach { index -> action(this[index]) } 
} 

使用法:あなたの代わりに、配列のリストを使用している場合

buf.forEachAt((0 until bufLimit).reversed)) {} 
// or 
buf.forEachAt(bufLimit - 1 downTo 0) {}