徳島ゲーム開発ごっこ 技術ブログ

ゲームを作るために役に立ったり立たなかったりする技術を学んでいきます!

【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()を七兆回使ってみてくださいー。

LINQのリンク