プログラミング勉強ノート

プログラミングで勉強した事を書いていきます。

C# LINQ to Objects (1)

LINQ to Objectsに関して勉強した部分のメモ1回目
基本的な部分のまとめ

  • Linq to Objectsとは
  • 遅延実行
  • 実体化

Linq to Objectsとは

IEnumeable<T>インターフェースを実装しているクラスに対して統一された操作(拡張メソッド)を提供するもの?

IEnumeable<T>インターフェースが実装されていれば、実体をあまり気にすることなくLinq to Objectsが提供する拡張メソッドを利用しデータに対しての処理を行う事が出来る。

Linq to Objectsが提供する拡張メソッド(一部のみ)

■ シーケンスの射影、要素の型と値を加工(遅延実行:実体化されない)
メソッド名 処理内容
Select 要素の型と値を加工する
SelectMany 2つのシーケンスの全ての組み合わせを行い、要素の型と値を加工する。
■ シーケンスのフィルタリング、要素絞込み(遅延実行:実体化されない)
メソッド名 処理内容
Where 条件を満たす要素を全て取得(フィルター処理)
Take 先頭から指定個数の要素を取得
TakeWhile 先頭から指定条件を満たす限り取得(途中で条件を満たさない要素があった場合はその時点で打ち切り)
Skip 先頭から指定個数の要素をスキップ
SkipWhile 先頭から指定条件を満たす限りスキップ(途中で条件を満たさない要素があった場合はその時点でスキップ終了)
■ シーケンスの結合(遅延実行:実体化されない)
メソッド名 処理内容
Join 一致するキーに基づいて2つのシーケンスを結合する
Zip 2つのシーケンスのマージを行う
■ シーケンスのグループ化(遅延実行:実体化されない)
メソッド名 処理内容
GroupBy 指定したキーでシーケンスのグループ化
GroupJoin 一致するキーに基づいて2つのシーケンスを結合した結果を指定したキーでグループ化
■ シーケンスから重複要素の除去(遅延実行:実体化されない)
メソッド名 処理内容
Distinct 1つのシーケンスから重複要素を除去し1つだけにする
■ シーケンスの結合(遅延実行:実体化されない)
メソッド名 処理内容
Concat 2つのシーケンスを結合する
■ シーケンスの集合演算(遅延実行:実体化されない)
メソッド名 処理内容
Union 2つのシーケンスの和集合を行う(重複する要素は除く)
Except 2つのシーケンスの差集合を行う
Intersect 2つのシーケンスの積集合を行う
■ シーケンスの並び替え(遅延実行:実体化されない)
メソッド名 処理内容
Reverse シーケンスの要素の順番を逆転させる
OrderBy シーケンスの要素を昇順で並び替える
ThenBy OrderByの結果を維持したままシーケンスの要素を昇順で並び替える
OrderByDescending シーケンスの要素を降順で並び替える
ThenByDescending OrderByDescendingの結果を維持したままシーケンスの要素を降順で並び替える
■ キャスト(遅延実行:実体化されない)
メソッド名 処理内容
Cast シーケンスの要素を指定した型にキャストする(キャストできない場合は例外発生)
OfType シーケンスの要素を指定した型にキャストする(キャストできない要素はシーケンスから除去する)
■ シーケンス作成(遅延実行:実体化されない)
メソッド名 処理内容
Range 指定値から1ずつ昇順で指定回数繰り返すシーケンスを作成する
Repeat 指定値を指定回数繰り返すシーケンスを作成する
■ 要素取得(即時実行:実体化される)
メソッド名 処理内容
First 条件を満たす先頭要素取得(取得できない場合は例外発生)
FirstOrDefault 条件を満たす先頭要素取得(取得できない場合は例外発生しない)
Last 条件を満たす最終要素取得(取得できない場合は例外発生)
LastOrDefault 条件を満たす最終要素取得(取得できない場合は例外発生しない)
ElementAt 指定Index位置の要素取得(取得できない場合は例外発生)
ElementAtOrDefault 指定Index位置の要素取得(取得できない場合は例外発生しない)
■ シーケンスの集計(即時実行:実体化される)
メソッド名 処理内容
Count シーケンスの要素数を取得
Max シーケンスの最大値を取得
Min シーケンスの最小値を取得
Sum シーケンスの合計値を取得
■ シーケンスが条件を満たすか判定(即時実行:実体化される)
メソッド名 処理内容
Any シーケンスの要素が一つでも条件を満たすか判定する(1つでも条件を満たせば処理を即終了、trueを返す)
All シーケンスの要素全てが条件を満たすか判定する
■ シーケンスからコレクションクラスへの変換(即時実行:実体化される)
メソッド名 処理内容
ToArray シーケンスから配列を作成する
ToList シーケンスからListを作成する
ToDictionary シーケンスからDictionaryを作成する
ToLookup シーケンスからILookupを作成する(1つのキーに対して複数の値を持てる読み取り専用のDictionaryのような物?)

遅延実行

  • Linq to Objectsの提供する拡張メソッドは遅延実行される物と即時実行される物がある。
  • 遅延実行される物は実際の処理は実体化されるまで行われない。

実体化

■ 実体化されるタイミング

  • 即時実行されるメソッドを呼ぶ(メソッド呼ばれたタイミングで要素毎にクエリが実行される)
  • foreachが実行される(ループ回る度に要素毎に定義したクエリが実行される)
// 1~10万までの値を表すシーケンス  
var datas = Enumerable.Range(1, 100000);

// 先頭100要素だけ欲しいのでTakeメソッドでフィルタリングする  
var takeDatas = datas.Take(100); 
// この時点ではまだ処理実行されておらず、クエリを定義しただけの状態、
// 実体化された際にシーケンスの要素毎にクエリが実行される、今回はTakeなので100要素取り出した時点で処理が終了するが  
// Whereだと全要素チェックするので全要素分定義したクエリが実行される  

// 実体化1 即時実行されるメソッドを呼ぶ  
var ArrayDatas = takeDatas.ToArray(); // ここで実際に定義したクエリが実行され、シーケンスから先頭100要素を取得する処理が行われ、配列化される  

// 実体化2 foreachを呼ぶ  
foreach(var item in takeDatas)  
{  
    ・・・   // ループが回るたびに、要素毎に定義したクエリが実行される。  
}  

■ 初回の実体化は重い

  • 実体化されていないシーケンスの場合、初回の実体化処理は結構重い
  • 実体化されていないシーケンスに対してElementAtを呼んでIndex毎にアクセス等すると毎回実体化の処理が走ってすごく重いので、そういう場合は一度実体化を行い、実体化したシーケンスに対して処理を行う