Kotlinの高階関数についてまとめたノート

スポンサーリンク

検証環境と備考

検証環境:IntelliJ IDEAのKotlin Notebook

備考1:Kotlinの高階関数の使い方を一通りまとめたものになります(高階関数ではないものもああります)。用語や分類に関しては正しくない可能性があります。

備考2:printlnを省略し変数の横に出力結果を表示している場合があります。

ラムダ式

ラムダ式は、名前を持たない関数(関数リテラル)です。変数に代入したり、関数の引数として直接渡したりできます。

基本構文

{ 引数1: 型, 引数2: 型 -> 処理 } の形式で記述します。

暗黙の引数

引数が1つだけの場合、引数の定義を省略して it という名前で参照できます。

トレーリングラムダ (Trailing Lambda)

関数の最後の引数が関数型である場合、ラムダ式を関数のカッコ () の外側に記述できます。

関数参照(::)

既存の関数やプロパティを、関数型の値として扱うための記法です。

基本構文

::関数名 で参照します。

プロパティ参照

プロパティ名に :: を付けることで、そのプロパティ自体(メタデータやゲッター)を参照できます。

クラスメソッドの参照

特定のクラスのメソッドを参照することも可能です。

コレクション操作関数

map

各要素を変換して、新しいリストを返します。

filter

条件に合う要素だけを抽出します。

fold (または reduce)

全要素を1つの値にまとめあげます。

flatMap

1つの要素から複数の要素を生成し、平坦化します。

associateBy

リストをMap(キー・値)に変換します。

groupBy

指定したキーで要素をグループ分けします。

partition

条件に「合うもの」と「合わないもの」にリストを2分割します。

distinctBy

特定のプロパティに基づいて重複を除去します。

zip

2つのリストを組み合わせて、ペアのリストを作ります。

sumOf

要素の特定のプロパティ(価格など)の合計を算出します。

maxByOrNull

最大のプロパティを持つ要素を取得します(空ならnull)。

sortedWith

compareBy と組み合わせて、複数の条件でソートします。

スライシング・チャンキング

windowed

指定したサイズでスライドさせます。

chunked

指定サイズで分割します。

zipWithNext

前後ペアを作る関数になります。

runningFold / runningReduce

途中経過を保持しリストを返します。

遅延評価

asSequence()

大量データを扱う際、中間リストを作成せずにパイプライン処理を行います。

カリー化・部分適用

カリー化

カリー化は、複数の引数を取る関数を、1つの引数を取る関数のチェーンに変換することです。
例えば $f(x, y, z)$ という関数を $f(x)(y)(z)$ という形に分解するプロセスを指します。
引数が増えると宣言する関数のシグネチャが長くなっていきますが、うまく利用するとBuilderパターンのようなチェーンができます。しかし、通常の実装ではカリー化を利用した実装よりデータクラスを利用した実装が現実的になる可能性があります。

部分適用

部分適用は、元の関数の引数リストのうち、一部にだけ値を放り込んで、残りの引数を後で受け取る状態にすることです。関数の特定の引数を固定化するために利用します。カリー化された関数を利用すると部分適用が柔軟にできます。

スコープ関数

let

nullチェックと組み合わせて、値を安全に別の形へ変換する際に多用します。

run

オブジェクトのプロパティを使いつつ、計算結果を返します。

also

値を書き換えずに、ログ出力などを差し込むのに適しています。

apply

オブジェクトの初期化設定を行い、そのオブジェクト自身を返します。例ではデータクラスを利用していますが、これはあまりよい例ではありません。データクラスを使用するなら変数はvalにし不変オブジェクトを用いて、copyメソッドの利用を検討すべきです。

with

特定のオブジェクトに対して複数の操作をまとめて行いたい場合に使います。

チェック関数

takeIf / takeUnless

条件を満たした時だけその値を返し、そうでなければ null を返します。
takeIfはAND条件をtakeUnlessはOR条件を作り出すことができます。ただし、まずは通常のif文やif式の利用を検討したほうが良いでしょう。

ifEmpty

コレクションが空の場合にデフォルト値を返します。

ループ

repeat(n) { ... }

指定回数処理を繰り返します。

表明(Assertion)

require(condition) / check(condition)

前提条件のガードをします。

インデックス付きのコレクション操作関数

mapIndexed

要素とそのインデックスをセットで変換します。

forEachIndexed

インデックスを使って副作用を実行します。

filterIndexed

インデックスを条件に抽出します。

indices / withIndex()

インデックス範囲の取得や分割代入。

indexOfFirst / indexOfLast

条件に一致する要素のインデックスを返します。

foldIndexed

累積計算にインデックスの情報を加味できます。

エラーハンドリング

runCatching

成功(Success)か失敗(Failure)をカプセル化した Result 型を返します。