以前にもこのリストのサブリストをつくる件は書いた。 いまつくっているアプリでちょうどリスト分割する機会があったので書き残す。
先に結論から。 1 から 8 までの文字(列)の list があり、これを 3個ずつサブリスト(グループ)にしたい。
main.kts
import kotlin.math.min
val list: List<String> = listOf("1","2","3","4","5","6","7","8")
val len = list.size
val buffer = 3
val listList: List<List<String>> = 0.until(len).step(buffer).map { index->
val start = index
val stop = min( (index + buffer), len)
list.subList(start, stop)
}
println( listList )
3個ずつ、の部分は buffer で指定しています。
0.until(len) すると、 0,1,2,3,... が産み出されるところを、 さらに step を入れることで、つまり 0.until(len).step(buffer) することで、 buffer 分ステップした 0,3,6,... が産み出されます。
なお、 list.subList は範囲外を指定するとエラーになるので、 つねに範囲を越えていないか確認して処理しています。
val stop = min( (index + buffer), len)
実行してみます。
$ kotlin -version
Kotlin version 1.8.10-release-430 (JRE 17.0.9+9-Ubuntu-122.04)
$ kotlin main.kts
[[1, 2, 3], [4, 5, 6], [7, 8]]
できました。
もし list が巨大だったら、 list.map {} で List<List<String>> を生成するのは 憚られるかもしれない。 その場合は、普通に for in を使う。
val len = list.size
val buffer = 3
for(index in 0.until(len).step(buffer)){
val start = index
val stop = min( (index + buffer), len)
val l = list.subList(start, stop)
// do something
println( "- $start .. $stop : $l" )
}
実行。
$ kotlin main.kts
- 0 .. 3 : [1, 2, 3]
- 3 .. 6 : [4, 5, 6]
- 6 .. 8 : [7, 8]
以上です。