2014/09/06

[C#]LINQを使った二重ループ(ネスト)の書き方

このエントリーをはてなブックマークに追加
ループ処理のなかでさらにループするような処理です。

LINQで二重ループ

LINQで多重ループするコードの書き方です。
例として、座標系に均等な点(Point)を作るコードを書きます。

// 二重ループの書き方
int[] list = { 10,20,30,40,50 };

// ①foreachを使う場合
List<Point> points1 = new List<Point>();
foreach(int x in list){
    foreach(int y in list){
        points1.Add(new Point(x, y));
    }
}

// ②クエリで書くとき
IEnumerable<Point> points2 =
    from x in list
    from y in list
    select new Point(x, y);

// ③メソッドで書くとき
IEnumerable<Point> points3 = list.SelectMany(x => list.Select(y => new Point(x,y)));
// SelectManyを使わないとIEnumerableが入れ子になる。IEnumerable<IEnumerable<Point>>

メソッドで書くときにしんどい

foreachと、クエリ式がものすごく簡潔に見えます。

メソッドで書いてると、あれ?どう書くんだ?と詰まってしまう。
list.Select(x => list.Select(y => new Point(x,y)));
とやると、当然ながら戻り値がIEnumerable<IEnumerable<Point>>という入れ子状態になるのです。
回避するため、SelectManyメソッドというがわざわざ用意されているようです。

見易さ、完結さとしては、ちょっと厳しいものがあるかな。
無理矢理一行にしている感じがあります。

三重ループだともう、書く気がしないですね。
そもそも、多重ループになるコードは見直したほうがいいっていう通説のほうが正しいのでしょうけれど。

0 件のコメント :

コメントを投稿