2015年07月26日

LINQ to Objectサンプル(23): 2重ループを記述する

  
今回が、このシリーズの最終回です。

まずは、いつものように、ループを使うコードから。
何をやっているかは、コードを読んでください。

■ループを使ったコード
int[,] nums = new int[,] {
     {13, 200,31, 43, 54 },
     {110,20, 330,410,50},
     {100,220,33, 40, 500}
};
var points = new List<Point>();
int ax = -1;
int ay = -1;
for (int x = 0; x <= nums.GetUpperBound(0); x++ ) {
    for (int y = 0; y <= nums.GetUpperBound(1); y++) {
        if (nums[x, y] > 400) {
            points.Add(new Point { X = x, Y = y });
        }
    }
}
foreach (var p in points)
    Console.WriteLine("({0}, {1})", p.X, p.Y);


上のコードの結果です。

(1, 3)
(2, 4)


■LINQを使ったコード
int[,] nums = new int[,] {
     {13, 200,31, 43, 54 },
     {110,20, 330,410,50},
     {100,220,33, 40, 500}
};
var points = GetAllPoints(nums).Where(p => nums[p.X,p.Y] > 400);
foreach (var p in points)
    Console.WriteLine("({0}, {1})", p.X, p.Y);
...
private static IEnumerable<Point> GetAllPoints(int [,] nums) {
    return from x in Enumerable.Range(0, nums.GetUpperBound(0) + 1)
           from y in Enumerable.Range(0, nums.GetUpperBound(1) + 1)
           select new Point { X = x, Y = y };
}


GetAllPoints をメソッドを定義している分、LINQのコードのほうが冗長になっていますね。
しかし、2重ループさせる箇所が何か所も何か所も出てきた場合はどうでしょうか?
2重ループを使ったコードのほうが、冗長になるのではと思います。

GetAllPointsというメソッドを定義したことで、IEnumerable<Point> として扱えるようになります。
つまり、Where以外にも、Select, Take, Aggregateなどなど様々な LINQの拡張メソッドを繋げて処理する ことができるということです。



 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52426782