Home About Contact
Kotlin

リストを n個ごとに分割する kotlin 編 その2

以前にもこのリストのサブリストをつくる件は書いた。 いまつくっているアプリでちょうどリスト分割する機会があったので書き残す。

結論

先に結論から。 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]

以上です。