0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Kotlin】Sequence から最大値と最小値を同時に求める

Last updated at Posted at 2019-11-15

記事「Javaにおける入力した5個の数字の内、最大値と最小値を求める」を読んで
Java の Stream でやってみようと思ったが、
reduce の使い方が分からなさすぎて挫折。

Kotlin で復讐することにした。

/**
 * シーケンスの最小値と最大値を返す。
 *
 * @param T シーケンスの要素の型。
 * @return シーケンスの最小値と最大値。シーケンスが空の場合は `null`。
 */
fun <T : Comparable<T>> Sequence<T>.minAndMax(): MinAndMax<T>? {
    // 拡張関数 `fold` 関数を使ってシーケンスの要素を1つの `MinAndMax` オブジェクトにまとめる。
    return fold(
        // 初期値は `null` とする。要素が1つもなければ結果は初期値のまま `null` となる。
        null as MinAndMax<T>?
    ) { minAndMax, element ->
        minAndMax
            // 最小値と最大値を更新する。
            ?.let {
                MinAndMax(
                    minOf(minAndMax.min, element),
                    maxOf(minAndMax.max, element)
                )
            }
        // `minAndMax` が `null` の場合、
        // 現在処理中の要素が1つめの要素ということになるため、
        // その値が最小値で有り最大値となる。
            ?: MinAndMax(element, element)
    }
}

/**
 * 最小値と最大値を保持するオブジェクト。
 */
data class MinAndMax<T : Comparable<T>>(
    val min: T,
    val max: T
)

使用例。

import kotlin.random.Random

fun main() {
    // 0以上100未満のランダムな整数を要素として持つシーケンスを生成する。
    generateSequence {
        // 0以上100未満のランダムな整数を生成する。
        Random.nextInt(100)
    }
        // 10要素だけを持つシーケンスにする。
        .take(10)
        // シーケンスの要素を標準出力する。
        .onEach { println("$it") }
        // シーケンスの要素の最小値と最大値を求める。
        .minAndMax()
        // 最小値と最大値が求まった(`minAndMax()` の返値が `null` でなかった、シーケンスが空でなかった)場合、
        // シーケンスの要素の最小値と最大値を標準出力する。
        ?.also { println("min: ${it.min}, max: ${it.max}") }
    // 求まらなかった場合、シーケンスが空であった旨を標準出力する。
        ?: println("Empty sequence.")
}

出力例。

34
99
24
73
7
82
98
58
19
87
min: 7, max: 99

なお、分解宣言は意図的に使わなかった。
慣れない人には分かりにくいため。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?