コレクションの一部を取得する
Kotlin標準ライブラリには、コレクションの一部を取得するための拡張関数が含まれています。 これらの関数は、結果のコレクションの要素を選択するためのさまざまな方法を提供します。具体的には、要素の位置を明示的にリストしたり、結果のサイズを指定したりすることができます。
Slice
slice()
は、指定されたインデックスを持つコレクション要素のリストを返します。インデックスは、範囲として渡すことも、整数のコレクションとして渡すこともできます。
fun main() {
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.slice(1..3))
println(numbers.slice(0..4 step 2))
println(numbers.slice(setOf(3, 5, 0)))
}
Take と drop
最初の要素から指定された数の要素を取得するには、take()
関数を使用します。 最後の要素を取得するには、takeLast()
を使用します。 コレクションのサイズよりも大きい数で呼び出された場合、両方の関数はコレクション全体を返します。
最初または最後の指定された数の要素を除くすべての要素を取得するには、それぞれdrop()
とdropLast()
関数を呼び出します。
fun main() {
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.take(3))
println(numbers.takeLast(3))
println(numbers.drop(1))
println(numbers.dropLast(5))
}
また、述語を使用して、取得または削除する要素の数を定義することもできます。 上記と同様の関数が4つあります。
takeWhile()
は、述語付きのtake()
です。述語に一致しない最初の要素まで(ただし、その要素は含まない)の要素を取得します。コレクションの最初の要素が述語に一致しない場合、結果は空になります。takeLastWhile()
はtakeLast()
に似ています。コレクションの末尾から述語に一致する要素の範囲を取得します。範囲の最初の要素は、述語に一致しない最後の要素の次の要素です。コレクションの最後の要素が述語に一致しない場合、結果は空になります。dropWhile()
は、同じ述語を持つtakeWhile()
の反対です。述語に一致しない最初の要素から最後までを返します。dropLastWhile()
は、同じ述語を持つtakeLastWhile()
の反対です。先頭から述語に一致しない最後の要素までを返します。
fun main() {
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.takeWhile { !it.startsWith('f') })
println(numbers.takeLastWhile { it != "three" })
println(numbers.dropWhile { it.length == 3 })
println(numbers.dropLastWhile { it.contains('i') })
}
Chunked
コレクションを指定されたサイズのパーツに分割するには、chunked()
関数を使用します。 chunked()
は単一の引数(チャンクのサイズ)を取り、指定されたサイズのList
のList
を返します。 最初のチャンクは最初の要素から始まり、size
個の要素を含み、2番目のチャンクは次のsize
個の要素を含み、以下同様です。最後のチャンクはサイズが小さくなる場合があります。
fun main() {
val numbers = (0..13).toList()
println(numbers.chunked(3))
}
返されたチャンクに対して、すぐに変換を適用することもできます。 これを行うには、chunked()
を呼び出すときに、変換をラムダ関数として提供します。 ラムダ引数はコレクションのチャンクです。chunked()
が変換とともに呼び出された場合、チャンクは短命なList
であり、そのラムダ内で直ちに消費されるべきです。
fun main() {
val numbers = (0..13).toList()
println(numbers.chunked(3) { it.sum() }) // `it` is a chunk of the original collection
}
Windowed
指定されたサイズのコレクション要素のすべての可能な範囲を取得できます。 それらを取得する関数はwindowed()
と呼ばれます。これは、指定されたサイズの移動ウィンドウを通してコレクションを見ているかのように見える要素範囲のリストを返します。 chunked()
とは異なり、windowed()
は各コレクション要素から始まる要素範囲(ウィンドウ)を返します。 すべてのウィンドウは、単一のList
の要素として返されます。
fun main() {
val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.windowed(3))
}
windowed()
は、デフォルト値を持つパラメーターに関して、より柔軟性を提供します。
step
は、隣接する2つのウィンドウの最初の要素間の距離を定義します。デフォルト値は1なので、結果にはすべての要素から始まるウィンドウが含まれます。ステップを2に増やすと、奇数要素から始まるウィンドウ(1番目、3番目など)のみを受け取ります。partialWindows
は、コレクションの末尾の要素から始まる、より小さいサイズのウィンドウを含めます。たとえば、3つの要素のウィンドウを要求した場合、最後の2つの要素に対しては作成できません。この場合partialWindows
を有効にすると、サイズ2と1の2つのリストが追加で含まれます。
最後に、返された範囲にすぐに変換を適用できます。 これを行うには、windowed()
を呼び出すときに、変換をラムダ関数として提供します。
fun main() {
val numbers = (1..10).toList()
println(numbers.windowed(3, step = 2, partialWindows = true))
println(numbers.windowed(3) { it.sum() })
}
2要素のウィンドウを構築するには、別の関数であるzipWithNext()
があります。 これは、レシーバコレクションの隣接する要素のペアを作成します。 zipWithNext()
はコレクションをペアに分割するわけではないことに注意してください。最後の要素を除く_各_要素に対してPair
を作成するため、[1, 2, 3, 4]
に対する結果は[[1, 2], [2, 3], [3, 4]]
であり、[[1, 2], [3, 4]]
ではありません。 zipWithNext()
は変換関数とともに呼び出すこともできます。その場合、レシーバコレクションの2つの要素を引数として受け取る必要があります。
fun main() {
val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.zipWithNext())
println(numbers.zipWithNext() { s1, s2 -> s1.length > s2.length})
}