1. 序章

Range は、Scalaで最も興味深い機能の1つです。 このチュートリアルでは、 Range Range を作成する方法、およびサポートされているいくつかのメソッドについて詳しく学習します。

2. 範囲の作成

Range は、が順序付けられた数値のコレクションを表すデータ型です。 正、負、および10進数の値に対してRangeを作成できます。 map filter foreach などのほとんどの収集メソッドを使用して、Rangeを反復処理することもできます。 範囲を作成する方法を見てみましょう。

2.1. コンパニオンオブジェクトの使用

Range.inclusive メソッドに開始値と終了値を指定することにより、Rangeを作成できます。 1から10までの整数の範囲を作成する方法を見てみましょう。

val rangeIncl = Range.inclusive(1,10)
rangeIncl.toList shouldBe List(1,2,3,4,5,6,7,8,9,10)

rangeIncl には、1と10の両方を含む1から10までの値が含まれます。

最終値を除外して範囲を作成する場合は、次を使用できます。

val rangeExcl = Range(1,10)
rangeExcl.toList shouldBe List(1,2,3,4,5,6,7,8,9)

これで、 rangeExcl には、終了値10を除いて、1から9までの値のみが含まれます。

2.2. toおよびuntilメソッドの使用

からおよびuntilのメソッドを使用して範囲を作成することもできます。

val rangeTo = 1 to 10
rangeTo.toList shouldBe List(1,2,3,4,5,6,7,8,9,10)

上記の式は、 Range.inclusive(1,10)とまったく同じです。

同様に、まで使用して排他範囲を作成できます。

val rangeUntil = 1 until 10
rangeUntil.toList shouldBe List(1,2,3,4,5,6,7,8,9)

3. 範囲ステップあり

Range を作成する場合、デフォルトのステップ値は1です。 つまり、範囲内の任意の2つの連続する値の間で、差は常に1になります。 キーワードbyを使用して、異なるステップ値で範囲を作成することもできます。 たとえば、次を使用して1から100までの奇数の範囲を作成できます。

val oddRange = 1 to 100 by 2
oddRange.head shouldBe 1
oddRange.last shouldBe 99

同様に、コンパニオンオブジェクトを使用して、ステップ値で範囲を作成することもできます。 たとえば、1から10までの奇数の範囲を作成するには:

val rangeStep = Range(1,10,2)
rangeStep.toList shouldBe List(1,3,5,7,9)

ステップを負の数として提供することもできます。

val reverseRange = 20 to 1 by -2
reverseRange.head shouldBe 20
reverseRange.last shouldBe 2

変数reverseRangeには、降順で20から2までの偶数が含まれます。

reverseRange で-2の代わりにステップ値2を使用するとどうなりますか? 20から開始して、正の数をステップとして使用して1に到達することはできないため、結果の範囲は空になります。

同様に、負の数の範囲を作成することもできます。

val negativeRange = -1 to -10 by -2
negativeRange.toList shouldBe List(-1,-3,-5,-7,-9)

4. 非整数範囲

これまで、整数の数値を持つ範囲を見てきました。 Decimal番号の範囲を作成することもできます。 ただし、10進数の範囲については、ステップ値を明示的に指定する必要があります。

val doubleRange = 1.0 to 2.0 by 0.2

これにより、 [1.0、1.2、1.4、1.6、1.8、2.0]の値を持つ範囲が作成されます。 ただし、 Double値を使用して範囲を構築するこの方法は、主に小数点近似の問題により、Scala2.12.6以降非推奨になっています。 このような範囲を作成するには、Doubleの代わりにBigDecimalを使用することをお勧めします。

val decimalRange = BigDecimal(1.0) to BigDecimal(2.0) by 0.2
decimalRange shouldBe List(1.0,1.2,1.4,1.6,1.8,2.0)

5. 範囲の便利なメソッド

コレクションに適用できるほとんどのメソッドは、Rangeにも適用できます。 適用できる最も便利な方法のいくつかを見てみましょう。

5.1. 反復とフィルター

map foreach filter 、および filterNot を使用して、範囲を反復およびフィルタリングできます。 これらのメソッドはすべて、トレイトTraversableLikeから継承されます。 toList メソッドを使用して、RangeListに変換することもできます。

val range = 1 to 10 

val evenNumbers = range.filter(_ % 2 == 0) 
evenNumbers shouldBe List(2,4,6,8,10)

val mappedRange = range.map(n => n*2) 
mappedRange shouldBe List(2,4,6,8,10,12,14,16,18,20)

5.2. テイクアンドドロップ

Range は、 drop take dropWhile takeWhile などの追加のメソッドも提供します。これらはすべて、別のメソッドを返します。 範囲

val range = 1 to 10

val take2:Range = range.take(2) 
take2.head shouldBe 1
take2.last shouldBe 2

val drop5:Range = range.drop(5)
drop5.head shouldBe 6
drop5.last shouldBe 10

6. 結論

このチュートリアルでは、Scalaの Range と、適用できる一般的な方法のいくつかについて学びました。 このチュートリアルで使用されているすべてのサンプルコードは、GitHubで単体テストとして利用できます。