LINQ

[C#/LINQ] Rangeメソッドの使い方 – 指定範囲の整数のシーケンスを作成

C#のLINQにおけるEnumerable.Rangeメソッドは、指定した範囲の整数シーケンスを生成するために使用されます。

このメソッドは2つの引数を取ります。

最初の引数はシーケンスの開始値、2つ目の引数は生成する整数の個数です。

例えば、Enumerable.Range(1, 5)は1から始まる5つの整数(1, 2, 3, 4, 5)を生成します。

このメソッドは、ループ処理や特定の範囲の数値を操作する際に便利です。

Enumerable.Rangeメソッドとは

Enumerable.Rangeメソッドは、C#のLINQ(Language Integrated Query)ライブラリに含まれる便利なメソッドの一つです。

このメソッドは、指定した開始値から始まり、指定した個数の整数を生成するシーケンスを作成します。

例えば、Enumerable.Range(1, 5)を使用すると、1から始まる5つの整数(1, 2, 3, 4, 5)が生成されます。

このメソッドは、数値のリストを簡単に作成したり、特定の範囲の整数を操作する際に非常に役立ちます。

特に、ループ処理やLINQクエリと組み合わせることで、データの操作やフィルタリングを効率的に行うことができます。

Enumerable.Rangeは、数値のシーケンスを生成するための強力なツールであり、さまざまなプログラミングシナリオで活用されています。

Enumerable.Rangeの基本的な使い方

シンプルな整数シーケンスの生成

Enumerable.Rangeメソッドを使用すると、簡単に整数のシーケンスを生成できます。

以下のコードは、1から5までの整数を生成する例です。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(1, 5); // 1から5までの整数を生成
        foreach (var number in numbers)
        {
            Console.WriteLine(number); // 各整数を出力
        }
    }
}
1
2
3
4
5

開始値と個数を指定する例

Enumerable.Rangeメソッドでは、開始値と生成する整数の個数を指定できます。

以下の例では、5から始まる10個の整数を生成しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(5, 10); // 5から始まる10個の整数を生成
        foreach (var number in numbers)
        {
            Console.WriteLine(number); // 各整数を出力
        }
    }
}
5
6
7
8
9
10
11
12
13
14
15

生成されたシーケンスの操作方法

生成されたシーケンスは、LINQメソッドを使用してさらに操作することができます。

例えば、生成した整数の中から偶数だけをフィルタリングすることができます。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var evenNumbers = Enumerable.Range(1, 10) // 1から10までの整数を生成
                                    .Where(n => n % 2 == 0); // 偶数をフィルタリング
        foreach (var number in evenNumbers)
        {
            Console.WriteLine(number); // 偶数を出力
        }
    }
}
2
4
6
8
10

foreachループでのシーケンスの利用

foreachループを使用して、生成されたシーケンスを簡単に反復処理できます。

以下の例では、1から10までの整数を生成し、それをforeachループで出力しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(1, 10); // 1から10までの整数を生成
        foreach (var number in numbers)
        {
            Console.WriteLine(number); // 各整数を出力
        }
    }
}
1
2
3
4
5
6
7
8
9
10

LINQクエリと組み合わせた使用例

Enumerable.Rangeメソッドは、LINQクエリと組み合わせて使用することができます。

以下の例では、1から20までの整数から、3の倍数を選択しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var multiplesOfThree = from n in Enumerable.Range(1, 20) // 1から20までの整数を生成
                               where n % 3 == 0 // 3の倍数を選択
                               select n;
        foreach (var number in multiplesOfThree)
        {
            Console.WriteLine(number); // 3の倍数を出力
        }
    }
}
3
6
9
12
15
18

Rangeメソッドの応用例

偶数や奇数のシーケンスを生成する

Enumerable.Rangeメソッドを使用して、偶数や奇数のシーケンスを簡単に生成できます。

以下の例では、1から20までの偶数を生成しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var evenNumbers = Enumerable.Range(1, 20) // 1から20までの整数を生成
                                    .Where(n => n % 2 == 0); // 偶数をフィルタリング
        foreach (var number in evenNumbers)
        {
            Console.WriteLine(number); // 偶数を出力
        }
    }
}
2
4
6
8
10
12
14
16
18
20

奇数のシーケンスを生成する場合は、条件を変更するだけです。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var oddNumbers = Enumerable.Range(1, 20) // 1から20までの整数を生成
                                   .Where(n => n % 2 != 0); // 奇数をフィルタリング
        foreach (var number in oddNumbers)
        {
            Console.WriteLine(number); // 奇数を出力
        }
    }
}
1
3
5
7
9
11
13
15
17
19

数学的なシーケンス(平方数やフィボナッチ数列)の生成

Enumerable.Rangeを使用して、平方数やフィボナッチ数列を生成することも可能です。

以下の例では、1から10までの平方数を生成しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var squares = Enumerable.Range(1, 10) // 1から10までの整数を生成
                                .Select(n => n * n); // 各整数の平方を計算
        foreach (var square in squares)
        {
            Console.WriteLine(square); // 平方数を出力
        }
    }
}
1
4
9
16
25
36
49
64
81
100

フィボナッチ数列を生成する場合は、少し異なるアプローチが必要です。

以下の例では、フィボナッチ数列の最初の10項を生成しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var fibonacci = new int[10]; // フィボナッチ数列の配列を作成
        fibonacci[0] = 0; // 初項
        fibonacci[1] = 1; // 第二項
        for (int i = 2; i < 10; i++)
        {
            fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]; // フィボナッチ数列を計算
        }
        foreach (var number in fibonacci)
        {
            Console.WriteLine(number); // フィボナッチ数を出力
        }
    }
}
0
1
1
2
3
5
8
13
21
34

配列やリストのインデックス操作に利用

Enumerable.Rangeメソッドは、配列やリストのインデックス操作にも利用できます。

以下の例では、配列のインデックスを使用して要素を取得しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var array = new string[] { "A", "B", "C", "D", "E" }; // 配列を作成
        var indices = Enumerable.Range(0, array.Length); // 配列のインデックスを生成
        foreach (var index in indices)
        {
            Console.WriteLine($"Index: {index}, Value: {array[index]}"); // インデックスと値を出力
        }
    }
}
Index: 0, Value: A
Index: 1, Value: B
Index: 2, Value: C
Index: 3, Value: D
Index: 4, Value: E

特定の範囲でのフィルタリング処理

Enumerable.Rangeを使用して、特定の範囲でのフィルタリング処理を行うことができます。

以下の例では、1から100までの整数から、30以上かつ70以下の整数をフィルタリングしています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var filteredNumbers = Enumerable.Range(1, 100) // 1から100までの整数を生成
                                         .Where(n => n >= 30 && n <= 70); // 特定の範囲でフィルタリング
        foreach (var number in filteredNumbers)
        {
            Console.WriteLine(number); // フィルタリングされた整数を出力
        }
    }
}
30
31
32
33
34
35
...(省略)
66
67
68
69
70

Rangeメソッドを使ったテストデータの生成

テストデータを生成する際にも、Enumerable.Rangeメソッドは非常に便利です。

以下の例では、ユーザーIDを生成してテストデータを作成しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var testData = Enumerable.Range(1, 10) // 1から10までのユーザーIDを生成
                                 .Select(id => $"User{id}"); // ユーザー名を生成
        foreach (var user in testData)
        {
            Console.WriteLine(user); // テストデータを出力
        }
    }
}
User1
User2
User3
User4
User5
User6
User7
User8
User9
User10

Rangeメソッドと他のLINQメソッドの組み合わせ

Whereメソッドとの組み合わせ

Whereメソッドを使用すると、Enumerable.Rangeで生成したシーケンスから特定の条件に合致する要素をフィルタリングできます。

以下の例では、1から20までの整数から偶数を選択しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var evenNumbers = Enumerable.Range(1, 20) // 1から20までの整数を生成
                                    .Where(n => n % 2 == 0); // 偶数をフィルタリング
        foreach (var number in evenNumbers)
        {
            Console.WriteLine(number); // 偶数を出力
        }
    }
}
2
4
6
8
10
12
14
16
18
20

Selectメソッドとの組み合わせ

Selectメソッドを使用すると、生成したシーケンスの各要素に対して変換処理を行うことができます。

以下の例では、1から10までの整数を生成し、それを2倍にしています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var doubledNumbers = Enumerable.Range(1, 10) // 1から10までの整数を生成
                                       .Select(n => n * 2); // 各整数を2倍に変換
        foreach (var number in doubledNumbers)
        {
            Console.WriteLine(number); // 2倍にした整数を出力
        }
    }
}
2
4
6
8
10
12
14
16
18
20

TakeやSkipメソッドとの組み合わせ

TakeメソッドSkipメソッドを使用することで、シーケンスの一部を取得したり、特定の数の要素をスキップすることができます。

以下の例では、1から20までの整数から最初の5つの整数を取得し、次に最初の5つをスキップしています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(1, 20); // 1から20までの整数を生成
        var firstFive = numbers.Take(5); // 最初の5つの整数を取得
        var skippedFive = numbers.Skip(5); // 最初の5つをスキップ
        Console.WriteLine("最初の5つの整数:");
        foreach (var number in firstFive)
        {
            Console.WriteLine(number); // 最初の5つを出力
        }
        Console.WriteLine("最初の5つをスキップした整数:");
        foreach (var number in skippedFive)
        {
            Console.WriteLine(number); // スキップした後の整数を出力
        }
    }
}
最初の5つの整数:
1
2
3
4
5
最初の5つをスキップした整数:
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

OrderByやReverseメソッドとの組み合わせ

OrderByメソッドReverseメソッドを使用して、生成したシーケンスの順序を変更することができます。

以下の例では、1から10までの整数を生成し、降順に並べ替えています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var orderedNumbers = Enumerable.Range(1, 10) // 1から10までの整数を生成
                                       .OrderByDescending(n => n); // 降順に並べ替え
        Console.WriteLine("降順に並べ替えた整数:");
        foreach (var number in orderedNumbers)
        {
            Console.WriteLine(number); // 降順にした整数を出力
        }
    }
}
降順に並べ替えた整数:
10
9
8
7
6
5
4
3
2
1

また、Reverseメソッドを使用して、生成したシーケンスの順序を反転させることもできます。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var reversedNumbers = Enumerable.Range(1, 10) // 1から10までの整数を生成
                                        .Reverse(); // 順序を反転
        Console.WriteLine("反転した整数:");
        foreach (var number in reversedNumbers)
        {
            Console.WriteLine(number); // 反転した整数を出力
        }
    }
}
反転した整数:
10
9
8
7
6
5
4
3
2
1

AnyやAllメソッドとの組み合わせ

AnyメソッドAllメソッドを使用して、生成したシーケンスの条件を確認することができます。

以下の例では、1から10までの整数の中に偶数が含まれているかを確認しています。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        var numbers = Enumerable.Range(1, 10); // 1から10までの整数を生成
        bool hasEvenNumbers = numbers.Any(n => n % 2 == 0); // 偶数が含まれているか確認
        Console.WriteLine($"偶数が含まれているか: {hasEvenNumbers}"); // 結果を出力
        bool allEvenNumbers = numbers.All(n => n % 2 == 0); // 全てが偶数か確認
        Console.WriteLine($"全てが偶数か: {allEvenNumbers}"); // 結果を出力
    }
}
偶数が含まれているか: True
全てが偶数か: False

このように、Enumerable.Rangeメソッドは他のLINQメソッドと組み合わせることで、さまざまなデータ操作を効率的に行うことができます。

Rangeメソッドのパフォーマンスと注意点

大規模なシーケンス生成時のパフォーマンス

Enumerable.Rangeメソッドは、指定した範囲の整数を生成する際に非常に効率的です。

特に、大規模なシーケンスを生成する場合でも、メモリを効率的に使用し、遅延評価を行うため、パフォーマンスが良好です。

生成されたシーケンスは、必要なときに必要な分だけ計算されるため、全ての整数を一度にメモリに保持する必要がありません。

ただし、非常に大きな範囲を指定する場合は、計算にかかる時間が増加する可能性があるため、注意が必要です。

メモリ使用量に関する注意点

Enumerable.Rangeメソッドは、生成する整数の範囲に応じてメモリを効率的に使用しますが、生成するシーケンスが非常に大きい場合、メモリ使用量が増加する可能性があります。

特に、数百万や数千万の整数を生成する場合、メモリの制約に注意する必要があります。

メモリ不足が発生すると、アプリケーションがクラッシュする可能性があるため、必要な範囲を適切に設定することが重要です。

無限ループに注意するケース

Enumerable.Rangeメソッドは、無限のシーケンスを生成することはできませんが、開始値や個数を不適切に設定すると、意図しない結果を引き起こす可能性があります。

例えば、開始値を負の数に設定し、個数を非常に大きく設定すると、生成されるシーケンスが期待したものとは異なる場合があります。

無限ループを避けるためには、開始値と個数を慎重に選定することが重要です。

範囲外の引数を指定した場合の挙動

Enumerable.Rangeメソッドにおいて、範囲外の引数を指定した場合、特に注意が必要です。

例えば、開始値がint.MaxValueに近い値で、個数を1以上に設定すると、オーバーフローが発生します。

この場合、ArgumentOutOfRangeExceptionがスローされます。

したがって、引数を指定する際には、範囲が適切であることを確認することが重要です。

以下は、範囲外の引数を指定した場合の例です。

using System;
using System.Linq;
class Program
{
    static void Main()
    {
        try
        {
            var numbers = Enumerable.Range(int.MaxValue, 2); // 範囲外の引数を指定
            // 10個の要素を出力
            foreach (var number in numbers.Take(10))
            {
                Console.WriteLine(number);
            }
        }
        catch (ArgumentOutOfRangeException ex)
        {
            Console.WriteLine($"エラー: {ex.Message}"); // エラーメッセージを出力
        }
    }
}
エラー: Specified argument was out of the range of valid values. (Parameter 'count')

このように、Enumerable.Rangeメソッドを使用する際には、引数の範囲に注意し、適切な値を指定することが重要です。

まとめ

この記事では、C#のEnumerable.Rangeメソッドの基本的な使い方や応用例、他のLINQメソッドとの組み合わせ、パフォーマンスや注意点について詳しく解説しました。

特に、整数のシーケンスを効率的に生成する方法や、さまざまなデータ操作に役立つテクニックを紹介しました。

これを機に、Enumerable.Rangeメソッドを活用して、より効率的なプログラミングを実践してみてください。

関連記事

Back to top button