2010年12月18日
SelectManyと2次元配列の素敵な関係 再び
前回の記事が不評だったので、
今度は、もうすこし真剣に考えてみる。
じゃあ、前回の記事はいい加減だったのか、と言われると、困るけど...
以下のような2次元配列があったとします。
通常、2次元配列の要素にアクセスするには、2重ループを書くのが普通だと思います。
上記コードでも、全要素にアクセスできますが、各要素の位置が分かりません。
そこで、LINQのSelectManyを使った、2次元配列のアクセスについて考えてみます。
例えば、上記配列の要素から、100より大きな数を取り出し、昇順に並べ替えたいとします。
その際に、その要素のインデックスも把握したいとしましょう。
SelectMany(2つのfrom句)を使うと、以下のように書くことができます。
これをfor文、foreach文を使って書くとすると、もっと多くのコードを書かないといけなくなると 思われます。
ただ、上記のように、インデックスの上限を決め打ちにしたくない場合は、
いちいち、2つのfrom句を書くのが面倒だったりします。
SelectMenyの部分を 拡張メソッドとして、定義すれば、さらに便利になりそうです。
そこで、 「予定は未定Blog版」の「SelectMany があればいいんじゃないだろうか?」の記事を参考にさせてもらいつつ、 以下のような拡張メソッドを定義してみました。
ここでは、3つの拡張メソッドを定義しています。
前述のコードだと、3つのうちの最初の Select メソッドが使えます。
クエリ式だと以下のように書けます。
2つめのSelectは、インデックスを受け取らないバージョンの Selectです。
ここでは、2倍した値が100より大きな値を昇順に表示しています。
最後の Sequential メソッドは、単純に、配列の要素を順に列挙するメソッドです。
じゃあ、前回の記事はいい加減だったのか、と言われると、困るけど...
以下のような2次元配列があったとします。
通常、2次元配列の要素にアクセスするには、2重ループを書くのが普通だと思います。
上記コードでも、全要素にアクセスできますが、各要素の位置が分かりません。
そこで、LINQのSelectManyを使った、2次元配列のアクセスについて考えてみます。
例えば、上記配列の要素から、100より大きな数を取り出し、昇順に並べ替えたいとします。
その際に、その要素のインデックスも把握したいとしましょう。
SelectMany(2つのfrom句)を使うと、以下のように書くことができます。
これをfor文、foreach文を使って書くとすると、もっと多くのコードを書かないといけなくなると 思われます。
ただ、上記のように、インデックスの上限を決め打ちにしたくない場合は、
いちいち、2つのfrom句を書くのが面倒だったりします。
SelectMenyの部分を 拡張メソッドとして、定義すれば、さらに便利になりそうです。
そこで、 「予定は未定Blog版」の「SelectMany があればいいんじゃないだろうか?」の記事を参考にさせてもらいつつ、 以下のような拡張メソッドを定義してみました。
ここでは、3つの拡張メソッドを定義しています。
前述のコードだと、3つのうちの最初の Select メソッドが使えます。
クエリ式だと以下のように書けます。
2つめのSelectは、インデックスを受け取らないバージョンの Selectです。
ここでは、2倍した値が100より大きな値を昇順に表示しています。
最後の Sequential メソッドは、単純に、配列の要素を順に列挙するメソッドです。
2010年12月16日
SelectManyと2次元配列の素敵な関係
この記事は、C# Advent Calendar jp: 2010 への参加記事(12/16分)です。
技術系Advent Calendarについては、こちらの記事をどうぞ。
これまでのC# Advent Calenderの記事を読んでみると、高度な話題が多く、僕をはじめ多くの人がついていけないのではないかと思ったり...
ということで、当初はかなりニッチな話題を書こうと思っていたのですが、それを取りやめ、もう少し易しい話題を取り上げたいと思います。
でも実用的かどうかは分かりませんが...
では、本題「SelectManyと2次元配列の素敵な関係」に入ります。
以下のような2次元配列があったとします。
通常、2次元配列の要素にアクセスするには、2重ループを書くのが普通だと思います。
上記コードでも、全要素にアクセスできますが、各要素の位置が分かりません。
ここでは、LINQのSelectManyを使い、2重ループを、一重のループにする方法をお見せします。
まずは、2次元配列にアクセスするためのインデックスのクラスを定義します。
名前がいまいちですが、それは置いといて、
次に、SelectManyを使い(2つの from を使い)、以下のようなメソッドを定義し ます。
これで、配列のすべてのインデックスを順に取り出すことができます。
ジェネリックメソッドにしているので、int以外の配列もOKです。
これは拡張メソッドにしても良いかもしれませんね。
ここまでが準備です。
そして、このAllPointsメソッドを使えば、配列のすべての要素にアクセスするのに、
と書くことができます。
配列から100より大きな値だけを抜き出したいなら、
と書けます。
foreach文もif文も使いたく無いという方は、次のように書くことができます。
2次元配列を扱うのに、もう2重ループは必要ありませんね。
技術系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重ループは必要ありませんね。



