2010年12月16日

SelectManyと2次元配列の素敵な関係  

   このエントリーをはてなブックマークに追加 mixiチェック Clip to Evernote
この記事は、C# Advent Calendar jp: 2010 への参加記事(12/16分)です。

技術系Advent Calendarについては、こちらの記事をどうぞ。

こちら「SelectManyと2次元配列の素敵な関係 再び 」もお読みいただければと思います。

これまでのC# Advent Calenderの記事を読んでみると、高度な話題が多く、僕をはじめ多くの人がついていけないのではないかと思ったり...
ということで、当初はかなりニッチな話題を書こうと思っていたのですが、それを取りやめ、もう少し易しい話題を取り上げたいと思います。
でも実用的かどうかは分かりませんが...


では、本題「SelectManyと2次元配列の素敵な関係」に入ります。

以下のような2次元配列があったとします。
通常、2次元配列の要素にアクセスするには、2重ループを書くのが普通だと思います。
上記コードでも、全要素にアクセスできますが、各要素の位置が分かりません。
ここでは、LINQのSelectManyを使い、2重ループを、一重のループにする方法をお見せします。

まずは、2次元配列にアクセスするためのインデックスのクラスを定義します。


名前がいまいちですが、それは置いといて、
次に、SelectManyを使い(2つの from を使い)、以下のようなメソッドを定義し ます。


これで、配列のすべてのインデックスを順に取り出すことができます。
ジェネリックメソッドにしているので、int以外の配列もOKです。
これは拡張メソッドにしても良いかもしれませんね。
ここまでが準備です。

そして、このAllPointsメソッドを使えば、配列のすべての要素にアクセスするのに、


と書くことができます。

配列から100より大きな値だけを抜き出したいなら、


と書けます。
foreach文もif文も使いたく無いという方は、次のように書くことができます。


2次元配列を扱うのに、もう2重ループは必要ありませんね。


この記事へのコメント
単に2重ループの方がいいんじゃないですか。
Posted by BLUEPIXY at 2010年12月16日 22:37
今回は、突っ込みどころが満載の記事みたいだなー(笑)。

僕が2次元配列使うのって、n * n のボード上のパズルを解く時くらいですが、
その時に、これと似たようなやり方を使っています。
「空きがどこか」とか「同じ色か」とか「いくつあるか」とか、あるいは、横一列の位置を列挙するとか、そういった処理を書くのに、IEnumerable<Point>としてすべて扱えれば、LINQの拡張メソッドとの相性がいいですし、コードも比較的すっきりとするんじゃないかと思います。

そういう意味では、例が良くなかったかもしれません。
Posted by Gushwell at 2010年12月17日 00:17
ああ、BLUEPIXY さんの

>単に2重ループの方がいいんじゃないですか。

は、SelectMany使わなくてもという意味ですね。
確かに、この記事だとその通りですね。

再度、書きなおして、新しい記事としてアップしなおします。
Posted by Gushwell at 2010年12月18日 10:28
 

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

http://trackback.blogsys.jp/livedoor/gushwell/52101333
この記事へのトラックバック
2次元配列を扱うのに、もう2重ループは必要ありませんね。 SelectManyと2次元配列の素敵な関係:窓際プログラマーの独り言 -C#の話題を中心に というのを読んで、むしろ LINQ っぽく扱えた方がうれしいんじゃないかな、と言うことで書いてみた。 static class Program { stat
[C#]SelectMany があればいいんじゃないだろうか?【予定は未定Blog版】at 2010年12月16日 22:12
前回の記事が不評だったので、 今度は、もうすこし真剣に考えてみる。 じゃあ、前回の記事はいい加減だったのか、と言われると、困るけど... 以下のような2次元配列があったとしま ...
SelectManyと2次元配列の素敵な関係再び【窓際プログラマーの独り言 -C#の話題を中心に】at 2010年12月19日 09:45