2012年03月30日

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

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


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


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

  

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

2012年01月12日

リストのすべての要素に対しラムダ式を適用する

   Clip to Evernote   このエントリーをはてなブックマークに追加      
リストをデリゲートが返す値で埋め尽くす では、リストをデリゲート(ラムダ式)の値で初期化する拡張メソッドを
示しましたが、今度は、既にリスト内にセットされている値に対し、ラムダ式を適用し、
新たな値をセットする拡張メソッドを示します。


この拡張メソッドを利用したコードです。

ここでは、各要素を1.05倍しています。
105 210 315 420
がリストの新たな要素となります。

この例では、ラムダ式の第1引数を利用していませんが、この i には、
その要素のインデックス番号がわたるので、そのインデックス値を使って、
要素の値に対し、処理をすることもできます。

ジェネリックなメソッドにしているので、リストの要素が文字列であってもOKです。
まったく、意味のないコードですが、以下にその例を示します。


リストには、順に

 "SILVERLIGHT"
 "INDOWS"
 "OX"
 "ROSOFT"

が格納されます。
  
Posted by gushwell at 22:00Comments(0)TrackBack(0)

2011年06月14日

stringの配列からDictionary<string, string>への変換をやってみた

   Clip to Evernote   このエントリーをはてなブックマークに追加      
元ネタ:stringの配列からDictionaryへの変換
http://d.hatena.ne.jp/okazuki/20110609/1307577527
http://d.hatena.ne.jp/okazuki/20110609/1307580225
http://d.hatena.ne.jp/okazuki/20110609/1307590523
http://d.hatena.ne.jp/okazuki/20110609/1307590592

僕もやってみました。
奇数番目の要素のシーケンスと偶数番目の要素のシーケンスを作成し、
Zipメソッドで、Tupleに変換したものを ToDictionaryメソッドで、Dictionaryに変換しています。
この例では、Zipメソッドは、拡張メソッドとして使うよりも、静的メソッドとして使った方が、
可読性が高くなると思います。

ジェネリックにしているので、文字列以外のシーケンスに対しても、利用できます。

もっと簡単に書けないかなー。
配列限定ならば、やはりfor文かな。

  
Posted by gushwell at 22:36Comments(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年08月03日

ForEach拡張メソッド

   Clip to Evernote   このエントリーをはてなブックマークに追加      
元ネタ: 何周目?(R.Tanaka.Ichiro's Blog)
     http://blogs.wankuma.com/rti/archive/2010/07/27/191691.aspx

こんな拡張メソッド書けば、もっと楽になります。


呼び出し側のコードです。
標準のコードと上記拡張メソッドを使ったコードを比較してみました。


標準として用意されてほしかったですね。
こういったクラスを集めてライブラリにしても、
いちいち参照設定するのが面倒だし、コードをblogに公開するときにも使えないし... 不便です。
  
Posted by gushwell at 23:42Comments(2)TrackBack(0)

2010年07月21日

StringCollection を string[] に変換

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

たぶん、ほとんど使われなくなったと思われる StringCollection クラスですが、 Visual Studio のプロジェクトの Properties フォルダにあるSettings.settings で設定した文字列リストは、StringCollection 型になっています。

これを stringの配列にしたいときのC#のコードです。


Enumerable.Cast メソッドで IEnumerableに型変換してあげれば、 LINQでおなじみの ToAray()メソッドで、string[] に変換できます。

C#2.0のときは、StringCollection.CopyToを使ったりしてましたが、Cast使うほうが直感的に 書けます。

  
Posted by gushwell at 22:32Comments(0)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)

2010年01月14日

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)

2009年11月11日

IOrderedEnumerableインターフェース

   Clip to Evernote   このエントリーをはてなブックマークに追加      
へー、こんなインターフェースがあったんですね。

IOrderedEnumerable<T>

いままでまったく意識してませんでした。
IOrderedEnumerable<T> 型のオブジェクトは、OrderBy または OrderByDescendingの戻り値の型です。
ThenBy 、 ThenByDescending でも、IOrderedEnumerable<T> 型のオブジェクトが得られます。

そうか、ThenBy 、 ThenByDescending は、IOrderedEnumerable<T> 型のオブジェクトが前提なんだ。
でも、どうやってるんだろうか。   
Posted by gushwell at 22:21Comments(0)TrackBack(0)

2009年10月25日

LINQのToDictionaryメソッドの動き

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


というオブジェクトに対して


とやったら、どうなるんだろうか。
試してみたところでは、Value の値でソートされ、その順番を保持して、 Dictionary オブジェクトに変換されているようだけれど、
これは、保障された動きなのだろうか?

  
Posted by gushwell at 22:38Comments(2)TrackBack(0)

2009年10月18日

LINQのToLookupメソッド

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

LINQの拡張メソッドに、Enumerable.ToLookupメソッドがあります。
このToLookUpメソッドは、Lookup 型を返すメソッドです。
Lookup型は、Dictionary に似ていますが、Dictionaryがキーを単一の値に割り当てるのに対して、Lookup はキーに対応する値がコレクションに割り当てられます。

以下のコードを見てください。

このコードは、ToLookUpメソッドで、ProductをCategoryIDごとにグルーピングしています。
foreachで取り出せるのは、IGrouping インターフェースのオブジェクトであり、 TKeyに対し、TElementのコレクションを保持しています。
この例では、[CategoryID, 該当する複数のProduct]を要素として持つコレクションとなります。
要素を取得するのに、2つのforeachを使い、CategoryIDに該当するProductName(複数)を表示しています。

図示できれば、もっと理解しやすいのだと思いますが、図を描くのは面倒なのでパスします。

この例では、あえて、型を明示したコードにしましたが、実際には、 varを使い、


と書いても良いと思います。   
Posted by gushwell at 22:33Comments(0)TrackBack(0)

2007年11月15日

C#3.0: 匿名クラスの日本語名フィールド

   Clip to Evernote   このエントリーをはてなブックマークに追加      
僕は、C#のソースコードに日本語識別名を使わない主義だが、
C#3.0では、例外を設けても良いかなと思い始めている。
それは、以下のようなコード。

var db = new NorthwndDataContext();
var products =
from p in db.Product
where p.Category.CategoryName.StartsWith("be")
select new {
ID = p.CategoryID,
Name = p.ProductName,
NumOrders = p.Order_Details.Count,
Revenue = p.Order_Details.Sum(o => o.UnitPrice * o.Quantity)
};
dataGridView1.DataSource = products;

ここで、匿名クラスを利用しているが、この匿名クラスに限っては、利用する価値があるかなと思うようになった。
ただし、その場合でも、匿名クラスのメンバー名を、そのままDataGridなどに表示する場合に限りたい。
上記コードを

var db = new NorthwndDataContext();
var products =
from p in db.Product
where p.Category.CategoryName.StartsWith("be")
select new {
番号 = p.CategoryID,
商品名 = p.ProductName,
注文数 = p.Order_Details.Count,
収入  = p.Order_Details.Sum(o => o.UnitPrice * o.Quantity)
};
dataGridView1.DataSource = products;

とすれば、グリッドのタイトル行を日本語で表示させることが可能だ。
  
Posted by gushwell at 21:55Comments(0)TrackBack(0)