Skip to content

コレクションの要素を取得する

Kotlin標準ライブラリには、コレクションの一部を取得するための拡張関数が含まれています。 これらの関数は、結果となるコレクションの要素を選択するためのさまざまな方法を提供します。例えば、要素の位置を明示的に指定したり、結果のサイズを指定したりすることができます。

Slice

slice()は、指定されたインデックスを持つコレクションの要素のリストを返します。インデックスはrangeとして渡すことも、整数の値のコレクションとして渡すこともできます。

kotlin

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()関数を呼び出します。

kotlin

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))
}

要素の取得または削除のために、述語(predicate)を使用することもできます。 上記で説明した関数と同様に、以下の4つの関数があります。

  • takeWhile() は、述語を伴うtake()です。述語に一致しない最初の要素を除く、それまでの要素を取得します。コレクションの最初の要素が述語に一致しない場合、結果は空になります。
  • takeLastWhile()takeLast()に似ています。述語に一致する要素の範囲をコレクションの末尾から取得します。その範囲の最初の要素は、述語に一致しない最後の要素の次の要素です。コレクションの最後の要素が述語に一致しない場合、結果は空になります。
  • dropWhile() は、同じ述語を持つtakeWhile()の反対です。述語に一致しない最初の要素から末尾までの要素を返します。
  • dropLastWhile() は、同じ述語を持つtakeLastWhile()の反対です。述語に一致しない最後の要素より前の要素から先頭までの要素を返します。
kotlin

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()は単一の引数、つまりチャンクのサイズを受け取り、指定されたサイズのListListを返します。 最初のチャンクは最初の要素から始まり、size個の要素を含みます。2番目のチャンクは次のsize個の要素を含み、以後同様です。最後のチャンクはサイズが小さくなる場合があります。

kotlin

fun main() {
    val numbers = (0..13).toList()
    println(numbers.chunked(3))
}

返されたチャンクに対して、その場で変換を適用することもできます。 これを行うには、chunked()を呼び出す際に変換をラムダ関数として提供します。 ラムダ引数はコレクションのチャンクです。変換を伴ってchunked()が呼び出された場合、チャンクは一時的なListであり、そのラムダ内で直ちに消費されるべきです。

kotlin

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の要素として返されます。

kotlin

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five")    
    println(numbers.windowed(3))
}

windowed()は、オプションのパラメータでより高い柔軟性を提供します。

  • stepは、2つの隣接するウィンドウの最初の要素間の距離を定義します。デフォルト値は1なので、結果にはすべての要素から始まるウィンドウが含まれます。stepを2に増やすと、奇数番目の要素(1番目、3番目など)から始まるウィンドウのみが取得されます。
  • partialWindowsは、コレクションの末尾にある要素から始まる、より小さいサイズのウィンドウを含めます。たとえば、3つの要素からなるウィンドウを要求した場合、最後の2つの要素に対してはウィンドウを構築できません。この場合、partialWindowsを有効にすると、サイズ2と1の2つのリストが追加で含まれます。

最後に、返された範囲に対して、その場で変換を適用することもできます。 これを行うには、windowed()を呼び出す際に変換をラムダ関数として提供します。

kotlin

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つの要素を引数として取る必要があります。

kotlin

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five")    
    println(numbers.zipWithNext())
    println(numbers.zipWithNext() { s1, s2 -> s1.length > s2.length})
}