[Kotlin] Range型とinキーワードで範囲を扱う

〇〇以下であれば<=といった不等号で表せますが、「〇〇から✕✕まで」といった範囲を指定するにはどうするのがいいでしょう?

今回はKotlinで「ここからここまで」を指定する範囲指定の方法を取り上げます。

不等号との使い分け

例えば0から100までの間の数値が入った変数があったとします。

この変数が「0から50である場合」を指定する場合はこのような記述で表せます。

num <= 50

では「50から70まで」を指定する場合は?

num >= 50 && num <= 70

これで「50以上であり、かつ70以下」を指定することはできます。しかしこの記述は無駄に長くなり、読む側としてもあまり読みやすいものではありません。

このような場合、範囲を指定する型とキーワードを使って記述することで、「ここからここまでに収まるかどうか」を簡潔に記述することができます。

範囲を表すIntRange型

まず始めに〇〇から✕✕までという範囲を表す型の記述方法です。

val range = 50..70

2つの数値をドット2つ(..)でつなげて書くと、IntRange型という範囲を表す型になります。IntelliJで入力してみると、型推論によってそれが確認できるかと思います。

範囲に収まるかどうかを判定するinキーワード

ある値が〇〇から✕✕の中に収まるという条件を指定するにはinキーワードを使います。まずは記述方法をチェックしましょう。

(チェックする値) in IntRange型

制御構文に組み込むとこんな感じ。ここではifを使用して、大学のテストの結果で単位が取れるかどうか、またその評価を算出する処理を記述してみます。

fun main(){
    val num = (0..100).shuffled().last()    //0から100までの乱数
    print(num)                  //点数を改行無しで出力

    val range = 80..89          //IntRange型の定数を宣言

    if (num < 60){               //乱数が60以下であれば...
        println("不可")
    }else if (num in 60..79){   //そうではなくて60から79の間であれば...
        println("可")
    }else if (num in range){   //80から89の間であれば...
        println("良")
    }else if (num >= 90){         //90以上であれば
        println("優")
    }
}
//82良

60未満や90以上のような指定方法であれば不等号の方が簡潔なので、ifの最初と最後の2つについては不等号で表しています。ここでは間の2つのelse ifに注目してください。

inキーワードの後に60..79や変数rangeといったIntRange型を置くことによって、numの値が設定したIntRange型の中に収まるかどうかを判定しています。

この記述はもちろん他の制御構文でも使えます。同じ処理をwhen式にしてみましょう。

val num = (0..100).shuffled().last()
print(num)

val range = 80..89

val result = when{
    num < 60->"不可"
    num in 60..79->"可"
    num in range->"良"
    num >= 90->"優"
}
println(result)

//59不可

より簡潔で見やすくなったのではないでしょうか。

範囲の応用: アルファベットでも使えるRange型

ここからは若干応用編になりますがこの範囲指定、実はアルファベットでも使用可能です。

試しにIntRange型の値を文字にしてみましょう。

CharRange型とClosedRange型

val range = 'e'..'m'

これは1文字限定のchar型の範囲、CharRange型。アルファベット順で範囲を指定します。文字はシングルクオートで囲みましょう。比較対象が1文字のChar型であるときはこちらを使います。

複数文字の文字列を指定するのであれば、

val range = "ac".."dc"

こちらは複数の文字列を範囲に設定できるClosedRange型。この型を使って1文字を指定することも可能です。

文字列の最初の文字がどの範囲に収まるか調べる

fun main(){
    println("iPhone" in "a".."n")
}
//true

iPhoneという文字列が、「aからnまでのアルファベット」から始まっているかどうかを調べるコードです。

範囲の指定を狭めてみてfalseになるかどうか、試してみてください。

ただしこのCharRange型やClosedRange型の範囲は、大文字小文字を区別することに注意が必要です。

val device = "iPhone"
println(device in "A".."Z")

//false

ClosedRange型の文字を大文字にすると、AからZの範囲に小文字のiは入っておらず、結果はfalseになります。

文字列の○文字目を指定して調べる

iPhoneの2文字目は大文字です。同じ条件で今度は2文字目を指定して調べてみましょう。以下の2つのコードは使用しているRange型が違いますが同じ意味です。

val device = "iPhone"
println(device[1] in 'A'..'Z')
//true
println("iPhone"[1].toString() in "A".."Z")
//true

文字列からある1文字を切り出すには他の方法もありますが、ここでは文字列を配列のように扱い、文字列のインデックス番号を指定して2文字目を切り出しています。

この場合途中の1文字のみを切り出しているので、in演算子の左辺はchar型になります。そのため演算子の後ろをシングルクオートにするか、切り出した1文字をtoString()で文字"列"に置き換えてください。

おさらい

色々と深いKotlinの範囲指定、今回は

  • 数値の範囲を表すIntRange型
  • 不等号との使い分け
  • inキーワード
  • 文字の範囲を表すCharRange型
  • 複数文字に対応したClosedRange型
  • 文字列を配列のように扱い、指定位置から1文字抜き出す方法

以上のことをお話しました。範囲の話題はまだたくさんありますが、長くなってしまうので後日に回したいと思います。

次回はKotlinの標準入力を使って、ユーザーとの対話プログラムを作ってみようというお話です。

タイトルとURLをコピーしました