2012年03月30日

FirstOrDefault使えばもっと簡潔に書けます。

   このエントリーをはてなブックマークに追加 Clip to Evernote
こちらのブログの「C#の表現力は圧倒的だ」の記事に、以下のようなコードがあります。


このコードは、以下のように書くこともできます。


この方が簡潔だし、効率も良いです。

  

Posted by gushwell at 23:57Comments(0)TrackBack(0)

2010年12月18日

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

   このエントリーをはてなブックマークに追加 Clip to Evernote
前回の記事が不評だったので、 今度は、もうすこし真剣に考えてみる。
じゃあ、前回の記事はいい加減だったのか、と言われると、困るけど...

以下のような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 メソッドは、単純に、配列の要素を順に列挙するメソッドです。

  
Posted by gushwell at 10:30Comments(0)TrackBack(1)

2010年12月16日

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

   このエントリーをはてなブックマークに追加 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重ループは必要ありませんね。
  
Posted by gushwell at 21:43Comments(3)TrackBack(2)

2010年10月29日

Any拡張メソッド

   このエントリーをはてなブックマークに追加 Clip to Evernote
指定した複数の値を繰り返すの記事に対して、neueccさんが、
IEnumerableを受け取るのにwhile(items.Any()) はよろしくない。
とつぶやいていました。
って、もう、半月も前のものだけれど...

なので、ちょっと書き換えてみました。
というコードを期待しているのかな?
それとも、もっと良い方法があるのかな?

まあ、Any拡張メソッドは、MSDNライブラリには、
「source の列挙は、結果が確認できるとすぐに停止します。」

とあるので、最悪でも最初の要素しかアクセスしないので、Count()メソッド使うよりも効率的だし、 僕が作成するアプリにおいては、実質的に問題になる事は無いと考えています。
それよりは、コード量が増えるほうがイヤです。

  
Posted by gushwell at 10:31Comments(6)TrackBack(0)

2010年04月26日

LINQのSelectManyで組合せを求める

   このエントリーをはてなブックマークに追加 Clip to Evernote

LINQにはSelectMany演算子がありますが、これを使うと簡単に重複ありの組合せを求めることができます。

たとえば、1,2,3,4 の中から2つを抜き出す組合せは

とすれば、求めることができます。
こちらに載せた「小町算」では、これを応用して、

といった計算式を求めています。
以下、その抜粋でです。


これで得た結果を、1□2□3□4□5□6□7□8□9の四角の中に入れれば計算式が出来上がります。

コードの全体は、こちらに掲載しています。

  
Posted by gushwell at 21:20Comments(0)TrackBack(0)

2010年03月10日

引数なし Enumerable.Any メソッド

   このエントリーをはてなブックマークに追加 Clip to Evernote
Enumerable.Any メソッドって、シーケンスの任意の要素が条件を満たしているかどうかを
判断する機能としてしか使っていなかったけど、引数が無いAnyメソッドってあったんですね。
要素の有無を調べることができます。
見落としていました。

int[] array1 = new int[] { 1,2,3 };
int[] array2 = new int[] { };
Console.WriteLine(array1.Any());
Console.WriteLine(array2.Any());

で、

True
False

が表示されます。
  
Posted by gushwell at 23:07Comments(0)TrackBack(0)

2009年12月15日

LINQのToListメソッド

   このエントリーをはてなブックマークに追加 Clip to Evernote
Ito Blogの LINQ における ToList メソッドにコメントできないみたいので、 こちらに書きます。

IEnumerable<T> を返すメソッドなんかを自作して、それをどんどんつなげて行くと最後に複雑なLINQのクエリが実行されて、ものすごく遅くなることがあるんですよね。

なので、意識的に ToList() などを呼んで即時実行させるときがあります。これだけで、速度がグンと速くなる場合があります。

ということで、List<T>にする必要はないけど、ToList()を呼び出すこともあります。
  
Posted by gushwell at 21:31Comments(4)TrackBack(0)

2009年12月08日

C#3.0での配列の比較

   このエントリーをはてなブックマークに追加 Clip to Evernote
もう4年以上前ですが、このブログで配列の比較をするコードを載せました。
今でも Googleの検索結果から、その記事のページを訪問してくれる人がいるようです。
そこでは、以下のようなコードを載せました。


とか


でも、C#3.0からはこんな必要はないですね。


という配列があった場合、


だけでOKです。自作のメソッドはもう不要です。
  
Posted by gushwell at 23:20Comments(2)TrackBack(0)