バッテラのハローワールド研究室

エンジニア、プログラミングに関する情報を掲載中!

【C#】System.Linqの基本的な使い方 (配列操作が非常に楽になりますよ)

はじめに

今回はC#におけるSystem.Linqについて勉強していこうと思います。

System.Linqは'''C#```の配列(コレクション)系の拡張メソッドを提供してくれます。

条件をつけて配列の中身を取り出したり、別のデータ型に変換するといった事ができるようになります。

あとSystem.LinqC#の標準ライブラリなので何もせず使えます。

条件一致したものだけ返す

Whereを使いましょう

var array = objects.Where(x => "条件式").ToList();

.ToList()としているのでWhereの戻り値がIEnumerable<T>型になっているためです。最終的に使う時にはList型の方が使いやすいです。

条件一致した最初のデータを返す

var obj = objects.Where(x => "条件式").FirstOrDefault();
First について

Firstというほぼ同じようなメソッドもありますが、こちらは一致しなかった場合に例外となってしまい使い勝手が悪いのでFirstOrDefaultを使うようにしています。

クラス型変数配列の最小/最大を返す

    public class Hoge : System.IComparable<Hoge>
    {
        public float Value { get; set; } = 0;

        public int CompareTo(Hoge other)
        {
            if (this.Value == other.Value)
            {
                return 0;
            }
            if (this.Value > other.Value)
            {
                return 1;
            }

            return -1;
        }
    }

public int CompareTo(Hoge other) を実装する必要があります

大なり小なりがどっち?なのかよく分からなくなりますが、
自分が相手より大きい場合は 1 、そうでなければ -1 となります。

objects.Min() 

要素が0でもクラス型はnullが返るのでそのままでいい

プリミティブ型(intやfloatなど)配列の最小/最大を返す

書き方例
objects.Select(x => x."変数名").Min(); // 最小
objects.Select(x => x."変数名").Max(); // 最大

Selectで必要な変数だけの配列に置き換えてるとこがポイントです。

もし配列の要素がない場合に null を返してあげたい場合

objects.Select(x => x."変数名").Min(val => ("データ型"?)val)

null許容型にするととで受けてを int? のような待ちにできる

あとは null条件演算子(??)を併用することで目的の処理を実装できる

value ?? -1 // これは value が nullだったら-1に置き換えするというコードである

条件にあてはまる最初のデータのインデックスを返す

データよりインデックス(for文などのiにあたるやつ)が欲しい時がありますよね?

デフォルトで用意はされていないので少し強引な形で実装しないといけないです。

実装方法
var index = objects.Select((item, index) => new { Index = index, Value = item })
                .Where(data => "条件式")
                .Select(data => data.Index)
                .First();
解説

まずSelectListの要素と要素番号をセットで持った新しいクラスを作ります、dataはその2つの変数を構造体と思ってください。

Whereで絞り込みしてヒットした最初の構造体のIndexを返すというものになります。

First ではなく FirstOrDefaultを使おう

Firstは配列の先頭の要素を返すメソッドなのですが、

要素が1つもなかった場合に例外発生します!

ユースケースとして絞り込みなどをした結果、要素が1つもないというのは普通にあることです。

なので少々使い勝手が悪いと思います。

そこで Firset の代わりに FirstOrDefault を使いましょうと言う話です。

FirstOrDefault はFiirstと同じ配列の先頭の要素を返すメソッドですが、 要素が1つもない場合にデータ型のdefault値が返ります。

default値のイメージですが↓のような感じです。

配列の型が プリミティブ(nt型など) なら 0
配列の方が クラス なら null

となります。

あとはnullチェックなどで要素がない場合の処理を作ればいいってことになります。