たこぜりー研究室

大腸菌DNAは4.64Mbp。酵母は13Mbpで、ヒトは3Gbp

スポンサーサイト

#
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

LINQ 探索 #1

#443
let 句がいまいち分からないので VSTS2008 Beta2 (VPC) 上で実験してみた。
let 句のサンプルの
string[] strings =
{
  "A penny saved is a penny earned.",
  "The early bird catches the worm.",
  "The pen is mightier than the sword."
};

// 母音で始まる単語を抽出
var query = from sentence in strings
  let words = sentence.Split(' ')
  from word in words
  let c = char.ToLower(word[0])
  where c == 'a' ||
    c == 'i' || c == 'u' || c == 'e' || c == 'o'
  select word;

を Debug モードでコンパイル、逆アセンブルして意訳 (匿名型、ラムダ式を適用) 。

すると、こうなる。
var query = strings
  .Select(sentence => new { sentence = sentence,
      words = sentence.Split(new char[] { ' ' }) })
  .SelectMany(x => x.words,
    (x, word) => new { x = x, word = word })
  .Select(y => new { y = y, c = char.ToLower(y.word[0]) })
  .Where(z =>
    {
      return z.c == 'a' || z.c == 'i' ||
        z.c == 'u' || z.c == 'e' || z.c == 'o';
    })
  .Select(z => z.y.word);

直感的にはこう↓なってほしいので、
var query = strings
  .SelectMany(sentence => sentence.Split(' '))
  .Select(word =>
    new { word = word, c = char.ToLower(word[0]) })
  .Where(x => x.c == 'a' || x.c == 'i' ||
    x.c == 'u' || x.c == 'e' || x.c == 'o')
  .Select(x => x.word);

これをビルドし .NET Reflector (Optimization : .NET 3.5) でみてみると、
var query = from sentence in strings
  select sentence.Split(new char[] { ' ' }) into word
  let c = char.ToLower(word[0])
  where c == 'a' ||
    c == 'i' || c == 'u' || c == 'e' || c == 'o'
  select word;

となった。
1 番目と 2 番目の let 句はリファレンス通り、違う使い方のようだ。
というより、最後に 'word' を参照しているから、select ... into ではダメなのか?

そもそも最後のコードを Visual Studio でやると、'word' が string[] と型推論されてコンパイルエラーになるのはなぜだ?

コメント

はじめまして。
最後のReflectorで見たクエリ式、↓であればほかと同じになりますね。
var query = from sentence in strings
select sentence.Split( new char[] { ' ' } ) into words
from word in words
let c = char.ToLower( word[ 0 ] )
where c == 'a' || c == 'i' || c == 'u' || c == 'e' || c == 'o'
select word;

ちなみに私なら join を使います。
var query2 = from sentence in strings
from word in sentence.Split( ' ' )
join b in "aiueo" on char.ToLower( word[ 0 ] ) equals b
select word;

  • 2008/01/06(日) 22:44:22 |
  • URL |
  • siokoshou #-
  • [ 編集 ]

どうもはじめましてです。

ははぁー join を使えばそんなにスマートになるんですねぇ。
勉強になります。


コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURL:  http://takojelly.blog2.fc2.com/tb.php/443-c77edc2f
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。