うら干物書き

ゲームを作りたい!

【C#,LINQ】Range~範囲内の連続した整数のシーケンスを作りたいとき~

 C#のLINQの関数であるRange()の使い方についてです。
 指定した整数から指定した数だけ、連続した整数の要素が入ったシーケンスを作成することが出来ます。
f:id:urahimono:20180617130053p:plain


この記事には.NET Framework 4.6.1を使用しています。

範囲内の連続した整数のシーケンスを作るよ

 いろんな地域で領土問題が起きていますね。
 ここからここまでが私の国、そこからそこまでがあなたの国、難しい問題です。

 難しい問題はさておき、特定の範囲の整数値が欲しいときはありませんか?
 そんなときはLINQRange()を使ってみてください。
 この関数に、どの整数値から何個分欲しいかを指定することで、連続した整数値のシーケンスを取得することができます。

public static IEnumerable<int> Range( int start, int count );
Enumerable.Range メソッド (Int32, Int32) (System.Linq)

Program.cs

using System.Linq;
using System.Collections;
using System.Collections.Generic;

public static class Program
{
    static void Main( string[] args )
    {
        // 1から5個の連続した値を取得するぞ!
        IEnumerable<int> intSequenceA    = Enumerable.Range(   1, 5 );
        // -1から3個の連続した値を取得するぞ!
        IEnumerable<int> intSequenceB    = Enumerable.Range(  -1, 3 );
        // 100から4個の連続した値を取得するぞ!
        IEnumerable<int> intSequenceC    = Enumerable.Range( 100, 4 );

        // 結果発表
        System.Console.WriteLine( "intSequenceA:{0}", intSequenceA.Text() );
        System.Console.WriteLine( "intSequenceB:{0}", intSequenceB.Text() );
        System.Console.WriteLine( "intSequenceC:{0}", intSequenceC.Text() );
        // 入力待ち用
        System.Console.ReadKey();
    }

    /// <summary>
    /// 簡易的なシーケンスのテキスト取得処理
    /// </summary>
    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }

} // class Program

intSequenceA:[1], [2], [3], [4], [5],
intSequenceB:[-1], [0], [1],
intSequenceC:[100], [101], [102], [103],

 このように使えます。
 負数から始めても大丈夫!

 Range()で取得したシーケンスに対して、Where()などを使ってフィルタリングすれば、もっと便利に活用できます。
 以下のコードでは、1~10までの連続した偶数のシーケンスを作成しています。

Program.cs

using System.Linq;
using System.Collections;
using System.Collections.Generic;

public static class Program
{
    static void Main( string[] args )
    {
        // 1から10個の連続した値の中から偶数だけを取得するぞ!
        IEnumerable<int> intSequence    = Enumerable.Range( 1, 10 ).Where( value => value % 2 == 0 );

        // 結果発表
        System.Console.WriteLine( "intSequence:{0}", intSequence.Text() );
        // 入力待ち用
        System.Console.ReadKey();
    }

    /// <summary>
    /// 簡易的なシーケンスのテキスト取得処理
    /// </summary>
    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }

} // class Program

intSequence:[2], [4], [6], [8], [10],

 ただし、使い方を間違えると例外が発生しますので、気をつけてください。
 Range()の第2引数に、0 を渡すことは問題ないのですが、負数を渡すと例外が発生します。

Program.cs

using System.Linq;
using System.Collections;
using System.Collections.Generic;

public static class Program
{
    static void Main( string[] args )
    {
        IEnumerable<int> intSequence = null;

        try
        {
            // 5から0個の連続した値を取得するぞ!
            intSequence = Enumerable.Range( 5, 0 );
        }
        catch( System.Exception i_exception )
        {
            System.Console.WriteLine( "5から0個の連続した値を取得:{0}", i_exception );
        }
        finally
        {
            if( intSequence != null )
            {
                System.Console.WriteLine( "5から0個の連続した値を取得:{0}", intSequence.Text() );
            }
        }

        intSequence = null;

        try
        {
            // 5から-1個の連続した値を取得するぞ!
            intSequence = Enumerable.Range( 5, -1 );
        }
        catch( System.Exception i_exception )
        {
            System.Console.WriteLine( "5から-1個の連続した値を取得:{0}", i_exception );
        }
        finally
        {
            if( intSequence != null )
            {
                System.Console.WriteLine( "5から-1個の連続した値を取得:{0}", intSequence.Text() );
            }
        }

        // 入力待ち用
        System.Console.ReadKey();
    }

    /// <summary>
    /// 簡易的なシーケンスのテキスト取得処理
    /// </summary>
    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }

} // class Program

5から0個の連続した値を取得:
5から-1個の連続した値を取得:System.ArgumentOutOfRangeException: 指定された引数は、有効な値の範囲内にありません。

 この点に気をつけてください。
 それでは多くの地域で領土問題が解決されることを祈って、Range()を七兆回使ってみてくださいー。