🗂

[Kotlin]Collection操作を8つの分類で解説④Retrieving collection

2024/03/31に公開

Collection操作を8つの分類で解説④Retrieving collection

前回から引き続き書いていきます!!!
4回目になりました。今回は、Retrieving collection を書いていきます!

< 分類表 >

collection operation 分類表

8つに分類したらこうなる!

collections operations 概要 関数
transformation
前の記事はここです⭐️
既存のコレクションから新しいコレクションを構築 Map, Zip, Associate, Flatten, StringPresentation
それぞれのメソッドは詳細でまた別途記載
Filtering
前の記事はここです⭐️
元のコレクションを変更せずに特定の条件で要素をフィルタリングし、新しいコレクションを返す filter() (filterIndexed()) ,filterNot(), filterNotNull(), partition(),any,all,none
Plus / Minus コレクションに要素を追加または削除するもの plus(), minus()
Grouping
前の記事はここです⭐️
コレクションの要素を特定の基準でグループ化するもの groupBy(), eachCount(),fold(), reduce(),aggregate()
Retrieving collection parts コレクションの一部を取得するもの slice() ,Chunked ,Windowed ,take()(takeLast(),takeLastWhile(),takeWhile()),drop()(dropLast(),dropLastWhile(),dropWhile()),
Retrieving Single Elements コレクションから単一の要素を取得するもの By position ( elementAt(), elementAtOrElse(), elementAtOrNull()), by condition(first(), firstOrNull(), last() , lastOrNull(),find() ),Check Element Existence(contains(), isEmpty(), isNotEmpty())
Ordering コレクションの要素を並べ替えるもの Natural order(sorted(), sortedDescending()), Custom orders( sortedBy(), sortedByDescending(), sortedWith() ),Reverse order( reversed()),Random order( shuffled())
Aggreregate Operation コレクションの要素を集計するもの reduce(), fold(), count(), sum(), average(), max(), min() etc

5. Retrieving collection parts

コレクションの一部を取得するものたち

Slice

与えられたインデックスを持つコレクション要素のリストを返す。
インデックスは、範囲として渡すことも、整数値のコレクションとして渡すことも可能。

val numbers = listOf("one", "two", "three", "four", "five", "six")    
println(numbers.slice(1..3)) // 出力 [two, three, four]
println(numbers.slice(0..4 step 2)) // 出力 [one, three, five]
println(numbers.slice(setOf(3, 5, 0))) // 出力 [four, six, one]   

Take and drop

関数 概要
take / takeLast 最初から(最後の要素から)指定された数の要素を取得。指定された数よりもコレクションのサイズが小さい場合、関数はコレクション全体を返す。
drop / dropLast 最初から(最後の)指定された数の要素を削除して残りを返す。
takeWhile / takeLastWhile 指定された条件を満たす最初の(最後の)要素までの要素を取得。
dropWhile / dropLastWhile 指定された条件を満たす最初の(最後の)要素から最後までの要素を削除して残りを返す。
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

// take(): 最初から指定された数の要素を取得
val takenNumbers = numbers.take(3)
println("Taken numbers: $takenNumbers") // 出力: Taken numbers: [1, 2, 3]

// drop(): 最初から指定された数の要素を削除して残りを返す
val droppedNumbers = numbers.drop(5)
println("Dropped numbers: $droppedNumbers") // 出力: Dropped numbers: [6, 7, 8, 9, 10]

// takeWhile(): 指定された条件を満たす最初の要素までの要素を取得
val takenWhileNumbers = numbers.takeWhile { it < 5 }
println("Taken numbers while condition is true: $takenWhileNumbers") // 出力: Taken numbers while condition is true: [1, 2, 3, 4]

// dropWhile(): 指定された条件を満たす最初の要素から最後までの要素を削除して残りを返す
val droppedWhileNumbers = numbers.dropWhile { it < 5 }
println("Dropped numbers while condition is true: $droppedWhileNumbers") // 出力: Dropped numbers while condition is true: [5, 6, 7, 8, 9, 10]


Chunked :chunked()

  • 元のコレクションを新しいリストのリストに分割する。指定されたサイズでコレクションを複数の部分に分割する。
  • 引数にはチャンクのサイズを指定し、その指定されたサイズのリストサイズのリストを返す。
  • 返されたチャンクに対して、すぐに変換を適用することも可能。ラムダでその処理を記述。

基本形

fun <T> Iterable<T>.chunked(size: Int): List<List<T>>

ex.

val numbers = (0..13).toList()
println(numbers.chunked(3))
// 出力 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13]]

// チャンクを加工: チャンクしたものに対して合計を出す 
println(numbers.chunked(3) { it.sum() })
// 出力 [3, 12, 21, 30, 25]

Windowed :windowed()

  • 指定したサイズのコレクション要素のすべての可能な範囲を取得
  • chunked()とは異なり、windowed()は各コレクション要素から始まる要素範囲(ウィンドウ)を返す。
  • オプションのパラメータもある
    • step: 隣接する2つのウィンドウの最初の要素間の距離を定義する。
       デフォルトでは値は1で、結果にはすべての要素から始まるウィンドウが含まれる。
    • partialWindows: コレクションの末尾の要素から開始するサイズの異なるウィンドウを含めるかどうかを指定。
      ex. 3つの要素のウィンドウをリクエストした場合、最後の2つの要素についてはウィンドウを構築できない。
       この場合、partialWindowsを有効にすると、サイズ2と1の2つの追加のリストが含まれるようになる。

ex.1

val numbers = listOf("one", "two", "three", "four", "five")    
println(numbers.windowed(3))
// 出力 [[one, two, three], [two, three, four], [three, four, five]]

println(numbers.windowed(3, step = 2, partialWindows = true))
// 出力 [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]]
println(numbers.windowed(3, step = 2, partialWindows = false))
// 出力 [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]]

ex.2

val sequence = generateSequence(1) { it + 1 }

val windows = sequence.windowed(size = 5, step = 1)
println(windows.take(4).toList()) // 出力 [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8]]

val moreSparseWindows = sequence.windowed(size = 5, step = 3)
println(moreSparseWindows.take(4).toList()) // 出力 [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8], [7, 8, 9, 10, 11], [10, 11, 12, 13, 14]]

val fullWindows = sequence.take(10).windowed(size = 5, step = 3)
println(fullWindows.toList()) // [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8]]

val partialWindows = sequence.take(10).windowed(size = 5, step = 3, partialWindows = true)
println(partialWindows.toList()) // 出力 [[1, 2, 3, 4, 5], [4, 5, 6, 7, 8], [7, 8, 9, 10], [10]]

6. Retrieving collection parts

メソッド 意味
By position elementAt 指定されたインデックスに対応する要素を取得
elementAtOrElse 指定されたインデックスに対応する要素を取得、範囲外ならデフォルト値を返す
elementAtOrNull 指定されたインデックスに対応する要素を取得、範囲外ならnullを返す
By condition first 最初の要素を取得
firstOrNull 最初の要素を取得、空ならnullを返す
last 最後の要素を取得
lastOrNull 最後の要素を取得、空ならnullを返す
find 条件を満たす最初の要素を取得、条件に合うものがなければnullを返す
Check Element Existence contains 指定された要素がコレクションに含まれるか判定
isEmpty コレクションが空か判定
isNotEmpty コレクションが空でないか判定

By position: elementAt/ elementAtOrElse / elementAtOrNull

ex.

val numbers = linkedSetOf("one", "two", "three", "four", "five")
println(numbers.elementAt(3)) // 出力 four

// Listにはgetが一般的
val numberList = listOf("one", "two", "three", "four", "five")
println(numberList.get(3)) // 出力 four

  • elementAtOrElse:
    指定されたインデックスが範囲外の場合に、代替の値を返す。
  • elementAtOrNull:
     指定されたインデックスが範囲外の場合に、null を返す。

ex.

val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.elementAtOrNull(5)) // 出力 null
println(numbers.elementAtOrElse(5) { index -> "The value for index $index is undefined"})
// 出力 The value for index 5 is undefined

By condition: first/last/ find

ex. first / last

val numbers = listOf("one", "two", "three", "four", "five", "six")

println(numbers.first { it.length > 3 }) // 出力 three
println(numbers.last { it.startsWith("f") }) // 出力 four

  • first , last 両者ともマッチする要素がない場合、例外を投げるので、
     避けるためには、代わりにNull許容な以下を使用できる。
    • firstOrNull (=findで代用可能!※findは要素見つからなければNullを返すため。)
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.firstOrNull { it.length > 6 }) // 出力 null
println(numbers.find { it.length > 6 }) // 出力 null

Check element existence:contains/isEmpty

  • contains
    • 指定された要素がコレクションに含まれるかの判定
    • in演算子で呼び出し可能
val numbers = listOf("one", "two", "three", "four", "five", "six")

println(numbers.contains("four")) // 出力 true
println("zero" in numbers) // 出力 false
  • isEmpty:
    • コレクションが空か判定する
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.isEmpty()) // 出力 false

Discussion