うら干物書き

ゲームを作りたい!

【C#,LINQ】Any~配列やリストの中で条件を満たしているものが一つでもあるかを判定したいとき~

 C#のLINQの関数であるAny()の使い方についてです。
 配列やリストなどのシーケンス内にて、一つでも指定した条件を満たした要素があるかを判定することが出来ます。
f:id:urahimono:20180625190914p:plain


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

配列やリストが空じゃないかを調べる

 LINQにはAny()という関数があります

public static bool Any<TSource>( this IEnumerable<TSource> source );
Enumerable.Any(TSource) メソッド (IEnumerable(TSource)) (System.Linq)

 これを使うことで、配列やリストといったIEnumerable<T>を継承したシーケンスが空かどうかを判定することができます。

Program.cs

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

public static class Program
{
    static void Main( string[] args )
    {
        // 空のデータ
        int[]   numbersA = new int[] { };
        int[]   numbersB = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        bool reaultA = numbersA.Any();
        bool reaultB = numbersB.Any();

        // 結果発表
        System.Console.WriteLine( "numbersA:{0}", numbersA.Text() );
        System.Console.WriteLine( "numbersB:{0}", numbersB.Text() );
        System.Console.WriteLine( "numbersAは要素がありますか:{0}", reaultA );
        System.Console.WriteLine( "numbersBは要素がありますか:{0}", reaultB );
        // 入力待ち用
        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

numbersA:
numbersB:[0], [1], [2], [3], [4], [5], [6], [7], [8], [9],
numbersAは要素がありますか:False
numbersBは要素がありますか:True

条件を満たした要素があるかどうかを調べる

 Any()には他にも使い方があります。
 Any()にはオーバーロードされたものがあり、引数に条件を記述することで、配列やリスト内に指定した条件を満たす要素が一つでもあるかを調べることが出来ます。

public static bool Any<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate );
Enumerable.Any(TSource) メソッド (IEnumerable(TSource), Func(TSource, Boolean)) (System.Linq)

 以下の例ではラムダ式を用いて条件文を記述しています。

Program.cs

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

public static class Program
{
    static void Main( string[] args )
    {
        // 0 ~ 9の数値データ
        int[]   numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        // 偶数の要素はありますか
        bool reaultA = numbers.Any( value => value % 2 == 0 );
        // 10以上の要素はありますか
        bool reaultB = numbers.Any( value => value >= 10 );
        // 5未満の要素はありますか
        bool reaultC = numbers.Any( value => value < 5 );

        // 結果発表
        System.Console.WriteLine( "numbers:{0}", numbers.Text() );
        System.Console.WriteLine( "偶数の要素はありますか  :{0}", reaultA );
        System.Console.WriteLine( "10以上の要素はありますか:{0}", reaultB );
        System.Console.WriteLine( "5未満の要素はありますか :{0}", reaultC );
        // 入力待ち用
        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

numbers:[0], [1], [2], [3], [4], [5], [6], [7], [8], [9],
偶数の要素はありますか :True
10以上の要素はありますか:False
5未満の要素はありますか :True

 Any()はシンプルで使いやすいので、是非とも七兆回ぐらい使ってみてください。