2012年03月30日
2012年01月12日
リストのすべての要素に対しラムダ式を適用する
リストをデリゲートが返す値で埋め尽くす では、リストをデリゲート(ラムダ式)の値で初期化する拡張メソッドを
示しましたが、今度は、既にリスト内にセットされている値に対し、ラムダ式を適用し、
新たな値をセットする拡張メソッドを示します。
この拡張メソッドを利用したコードです。
ここでは、各要素を1.05倍しています。
105 210 315 420
がリストの新たな要素となります。
この例では、ラムダ式の第1引数を利用していませんが、この i には、
その要素のインデックス番号がわたるので、そのインデックス値を使って、
要素の値に対し、処理をすることもできます。
ジェネリックなメソッドにしているので、リストの要素が文字列であってもOKです。
まったく、意味のないコードですが、以下にその例を示します。
リストには、順に
"SILVERLIGHT"
"INDOWS"
"OX"
"ROSOFT"
が格納されます。
示しましたが、今度は、既にリスト内にセットされている値に対し、ラムダ式を適用し、
新たな値をセットする拡張メソッドを示します。
この拡張メソッドを利用したコードです。
ここでは、各要素を1.05倍しています。
105 210 315 420
がリストの新たな要素となります。
この例では、ラムダ式の第1引数を利用していませんが、この i には、
その要素のインデックス番号がわたるので、そのインデックス値を使って、
要素の値に対し、処理をすることもできます。
ジェネリックなメソッドにしているので、リストの要素が文字列であってもOKです。
まったく、意味のないコードですが、以下にその例を示します。
リストには、順に
"SILVERLIGHT"
"INDOWS"
"OX"
"ROSOFT"
が格納されます。
2011年06月14日
stringの配列からDictionary<string, string>への変換をやってみた
元ネタ: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文かな。
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文かな。
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重ループは必要ありませんね。
2010年08月03日
ForEach拡張メソッド
元ネタ: 何周目?(R.Tanaka.Ichiro's Blog)
http://blogs.wankuma.com/rti/archive/2010/07/27/191691.aspx
こんな拡張メソッド書けば、もっと楽になります。
呼び出し側のコードです。
標準のコードと上記拡張メソッドを使ったコードを比較してみました。
標準として用意されてほしかったですね。
こういったクラスを集めてライブラリにしても、
いちいち参照設定するのが面倒だし、コードをblogに公開するときにも使えないし... 不便です。
http://blogs.wankuma.com/rti/archive/2010/07/27/191691.aspx
こんな拡張メソッド書けば、もっと楽になります。
呼び出し側のコードです。
標準のコードと上記拡張メソッドを使ったコードを比較してみました。
標準として用意されてほしかったですね。
こういったクラスを集めてライブラリにしても、
いちいち参照設定するのが面倒だし、コードをblogに公開するときにも使えないし... 不便です。
2010年07月21日
StringCollection を string[] に変換
たぶん、ほとんど使われなくなったと思われる StringCollection クラスですが、 Visual Studio のプロジェクトの Properties フォルダにあるSettings.settings で設定した文字列リストは、StringCollection 型になっています。
これを stringの配列にしたいときのC#のコードです。
Enumerable.Cast
C#2.0のときは、StringCollection.CopyToを使ったりしてましたが、Cast使うほうが直感的に 書けます。
2010年04月26日
LINQのSelectManyで組合せを求める
2010年03月10日
引数なし Enumerable.Any メソッド
Enumerable.Any メソッドって、シーケンスの任意の要素が条件を満たしているかどうかを
判断する機能としてしか使っていなかったけど、引数が無いAnyメソッドってあったんですね。
要素の有無を調べることができます。
見落としていました。
int[] array1 = new int[] { 1,2,3 };
int[] array2 = new int[] { };
Console.WriteLine(array1.Any());
Console.WriteLine(array2.Any());
で、
True
False
が表示されます。
判断する機能としてしか使っていなかったけど、引数が無いAnyメソッドってあったんですね。
要素の有無を調べることができます。
見落としていました。
int[] array1 = new int[] { 1,2,3 };
int[] array2 = new int[] { };
Console.WriteLine(array1.Any());
Console.WriteLine(array2.Any());
で、
True
False
が表示されます。
2010年01月14日
LINQ to XML 目次
2009年12月15日
LINQのToListメソッド
Ito Blogの LINQ における ToList メソッドにコメントできないみたいので、
こちらに書きます。
IEnumerable<T> を返すメソッドなんかを自作して、それをどんどんつなげて行くと最後に複雑なLINQのクエリが実行されて、ものすごく遅くなることがあるんですよね。
なので、意識的に ToList() などを呼んで即時実行させるときがあります。これだけで、速度がグンと速くなる場合があります。
ということで、List<T>にする必要はないけど、ToList()を呼び出すこともあります。
IEnumerable<T> を返すメソッドなんかを自作して、それをどんどんつなげて行くと最後に複雑なLINQのクエリが実行されて、ものすごく遅くなることがあるんですよね。
なので、意識的に ToList() などを呼んで即時実行させるときがあります。これだけで、速度がグンと速くなる場合があります。
ということで、List<T>にする必要はないけど、ToList()を呼び出すこともあります。
2009年12月08日
C#3.0での配列の比較
もう4年以上前ですが、このブログで配列の比較をするコードを載せました。
今でも Googleの検索結果から、その記事のページを訪問してくれる人がいるようです。
そこでは、以下のようなコードを載せました。
とか
でも、C#3.0からはこんな必要はないですね。
という配列があった場合、
だけでOKです。自作のメソッドはもう不要です。
今でも Googleの検索結果から、その記事のページを訪問してくれる人がいるようです。
そこでは、以下のようなコードを載せました。
とか
でも、C#3.0からはこんな必要はないですね。
という配列があった場合、
だけでOKです。自作のメソッドはもう不要です。
2009年11月11日
IOrderedEnumerableインターフェース
へー、こんなインターフェースがあったんですね。
IOrderedEnumerable<T>
いままでまったく意識してませんでした。
IOrderedEnumerable<T> 型のオブジェクトは、OrderBy または OrderByDescendingの戻り値の型です。
ThenBy 、 ThenByDescending でも、IOrderedEnumerable<T> 型のオブジェクトが得られます。
そうか、ThenBy 、 ThenByDescending は、IOrderedEnumerable<T> 型のオブジェクトが前提なんだ。
でも、どうやってるんだろうか。
IOrderedEnumerable<T>
いままでまったく意識してませんでした。
IOrderedEnumerable<T> 型のオブジェクトは、OrderBy または OrderByDescendingの戻り値の型です。
ThenBy 、 ThenByDescending でも、IOrderedEnumerable<T> 型のオブジェクトが得られます。
そうか、ThenBy 、 ThenByDescending は、IOrderedEnumerable<T> 型のオブジェクトが前提なんだ。
でも、どうやってるんだろうか。
2009年10月25日
LINQのToDictionaryメソッドの動き
というオブジェクトに対して
とやったら、どうなるんだろうか。
試してみたところでは、Value の値でソートされ、その順番を保持して、 Dictionary オブジェクトに変換されているようだけれど、
これは、保障された動きなのだろうか?
2009年10月18日
LINQのToLookupメソッド
LINQの拡張メソッドに、Enumerable.ToLookupメソッドがあります。
このToLookUpメソッドは、Lookup
Lookup型は、Dictionary
以下のコードを見てください。
このコードは、ToLookUpメソッドで、ProductをCategoryIDごとにグルーピングしています。
foreachで取り出せるのは、IGrouping
この例では、[CategoryID, 該当する複数のProduct]を要素として持つコレクションとなります。
要素を取得するのに、2つのforeachを使い、CategoryIDに該当するProductName(複数)を表示しています。
図示できれば、もっと理解しやすいのだと思いますが、図を描くのは面倒なのでパスします。
この例では、あえて、型を明示したコードにしましたが、実際には、 varを使い、
と書いても良いと思います。
2007年11月15日
C#3.0: 匿名クラスの日本語名フィールド
僕は、C#のソースコードに日本語識別名を使わない主義だが、
C#3.0では、例外を設けても良いかなと思い始めている。
それは、以下のようなコード。
ここで、匿名クラスを利用しているが、この匿名クラスに限っては、利用する価値があるかなと思うようになった。
ただし、その場合でも、匿名クラスのメンバー名を、そのままDataGridなどに表示する場合に限りたい。
上記コードを
とすれば、グリッドのタイトル行を日本語で表示させることが可能だ。
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;
とすれば、グリッドのタイトル行を日本語で表示させることが可能だ。



