VB のたまご

作成日: 2015/12/03, 更新日: 2015/12/03


LINQ を知って、複雑な処理をシンプルに変えよう

LINQ って、何だっけ?

  •  VB2008 から、LINQ(リンク) が使えるようになりました。皆さん LINQ 使っていますか? LINQ ってなんだかよく分からないのよね~とか、最近の流行にはもうついていけないわ~という方のために、 LINQ を覚えるとこんなに便利になるよ。ということをちょっと盛って説明したいと思います。

スポンサーリンク


LINQ の有無による、実装量の比較

  •  「LINQ は、プログラム上の SQL 言語」、「西の SQL、東の LINQ」みたいな事を、ちらっとでも見たり聞いたりしたことはありませんか。 LINQ を使うと、VB.NET 言語なのに SQL 言語を書いているような、不思議な感覚があります。これには、思わず心が躍ってしまいます。

  •  SQL 言語が出てきましたが、皆さん SQL Server とか、Oracle とか、データベース( DB )を扱った経験はありますか? DB からデータを取得する際、SQL を投げてデータをもらってきます。 SQL には、任意のデータのみ取得できるように、条件分岐命令があり、データの並び順を変えるために、ソート命令があり、と、 細かい制御ができます。

  •  SQL の書き方はシンプルで、複雑な命令を書いたとしても、VB.NET で書くよりは簡潔に表現することができます。 だから、思わずツイートしてしまいます。「あ~、VB.NET でもこういう風に書けたら楽なんだけどな~」。 時が経ち、それは LINQ という形で実現しました。

  •  それでは、普段通りに書いた場合と、LINQ を扱った場合で、どう変わるのか見てみましょう。


  • 普段通りに書いた場合
  • ' Integer 型のリストデータについて、偶数でかつ5以上のデータを、逆順で取得する
    Dim lst1 As New List(Of Integer)(New Integer() {8, 1, 10, 7, 3, 4, 5, 2, 6, 9})
    Dim lst2 As New List(Of Integer)
    
    For Each i As Integer In lst1
        If i Mod 2 = 0 AndAlso 5 < i Then
            lst2.Add(i)
        End If
    Next
    
    lst2.Sort()
    lst2.Reverse()
    
    For Each i As Integer In lst2
        Console.WriteLine(i)
    Next
    
    ' 出力結果
    10
    8
    6
    

  • LINQ で書いた場合(クエリ構文)
  • ' Integer 型のリストデータについて、偶数でかつ5以上のデータを、逆順で取得する
    Dim lst1 = New Integer() {8, 1, 10, 7, 3, 4, 5, 2, 6, 9}
    Dim lst2 = From i In lst1
               Where i Mod 2 = 0 AndAlso 5 < i
               Order By i Descending
    
    ' 取得結果の表示
    lst2.ToList().ForEach(Sub(i) Console.WriteLine(i))
    
    ' 出力結果
    10
    8
    6
    

  • LINQ で書いた場合(メソッド構文)
  • ' Integer 型のリストデータについて、偶数でかつ5以上のデータを、逆順で取得する
    Dim lst1 = New Integer() {8, 1, 10, 7, 3, 4, 5, 2, 6, 9}
    Dim lst2 = lst1.
               Where(Function(i) i Mod 2 = 0 AndAlso 5 < i).
               OrderByDescending(Function(i) i)
    
    ' 取得結果の表示
    lst2.ToList().ForEach(Sub(i) Console.WriteLine(i))
    
    ' 出力結果
    10
    8
    6
    

  •  お題として、Integer 型のコレクションデータがあり、大小バラバラに登録されています。 このデータに対して、偶数だけに絞り、5以上の値だけ取得して、さらに大きい順で取得してくる。という処理を作成します。 例題で多く使われるものですね。

  •  どうでしょうか。3つとも同じ処理をしています。ここでは、LINQ の使い方は知らなくても問題ありません。 クエリ構文とかメソッド構文がよく分からなくてもOKです。見た目のフィーリングだけで見ていただきたいです。 LINQ で書いた方は、SQL っぽく見えませんか。見た目もコード量もシンプルになりました。 For 命令は消えて If 文は1行です。ソートも1行で済みます。便利だと思いませんか? ちょっとでも LINQ について興味を持たれた方は、簡単な処理で十分なので、ぜひトライしてみてくださいね。

スポンサーリンク


LINQ にトライ!

  •  ということで、ちょっとだけ、トライしてみませんか。簡単なやつで。

  •  LINQ の書き方には、2通りあります。
  • SQL 言語風に記述するクエリ構文、メソッドチェーン的に記述するメソッド構文です。 なんで2種類もあるんだろうと当時は思いました。どっちを使えばいいの?と。 今考えれば、それは For 文と For Each 文の違いみたいなものだと思っています。 ※メソッドチェーンというのは、Dim result = Aaa().Bbb().Ccc() みたいに、戻り値をそのまま次のメソッドに渡していく形式のことです。

LINQ 入門(クエリ構文編)

  •  SQL に似ているといっても、それっぽい感じはありますが、 完全に SQL と同じわけではないので、書き方に慣れる前ではちょっと戸惑いがあります。それは出だしです。
  • SQL での書き方
    SELECT    field1
    FROM      table
    WHERE     field2 = xxx
    
    LINQ での書き方
    From    field1
    In      table
    Where   field2 = xxx
    Select  field1
    

  •  SQL での FROM キーワードはテーブル名を指定するが、VB.NET では、In キーワードでテーブル名を指定します。 SQL に似ているけど SQL を操作するという頭でいるとエラーになってしまうので、もどかしさが最初ありますが、 そんなのすぐに慣れます。この出だしでつまづいて諦めてしまうなんて、もったいないですよ!そこまでの価値が LINQ にはあります。 さくっと、乗り越えてしまいましょう。

  •  SQL の場合、欧米な書き方なんです。
  • 「I Like sushi.(私、好き、寿司。)」→「field1取ってくる、table から、Field2=xxx の条件に合うやつ。」。みたいな感じです。

  •  対して、LINQ の場合、日本語みたいな書き方なんです。
  • 「私は寿司が好きです。」→「この table から、field2=xxx の条件で、field1 を取ってこよう。」。みたいな感じです。

  •  LINQ の書き方は、VB.NET 言語そのままで、上から順に命令が実行されていきます。 だから、For 文で1つ1つ見ていって、If 文で条件に合うもの探して、条件に当てはまったものだけとってくる。という風に書きます。 これは、今までの書き方そのものですよね。

  • From field1 In table 。これは、For Each field1 In table みたいなものです。
  • Where field2 = xxx 。これは、If field2 = xxx Then みたいなものです。
  • Select Field1 。これは、扱いたいプロパティ名を指定します。


LINQ 入門(メソッド構文編)

  •  クエリ構文よりも、メソッド構文の方がいつもの VB.NET らしさがありますね。メソッド経由なので。
  • Dim lst2 = lst1.
               Where(Function(i) i Mod 2 = 0 AndAlso 5 < i).
               OrderByDescending(Function(i) i)
    
    Dim lst2 = lst1.Where(Function(i) i Mod 2 = 0 AndAlso 5 < i).OrderByDescending(Function(i) i)
    

  •  先程分かりやすくするために、メソッド構文も1つ1つ改行して書いていますが、1行で書くとこういう風に(区切りが見づらく)見えます。 でも最近は、メソッド構文をいっぱい書くようになりました。処理順序の分かりやすさと、メソッドにラムダ式を渡してつなげる方が、VB.NET っぽさがあるからかな? フィーリングなので、なんとも分かりづらいところではありますね。


まとめ

  •  このサンプルでは、型推論を利用して、型宣言は省略しています。 また、出てきませんでしたが、Select キーワードを使う際は、匿名型データのジェネリックコレクションデータとして、戻り値を受け取ることがあります。 この場合も、型推論で受け取ります。 メソッド構文では、ラムダ式を使っていますし、LINQ を使えるようになるためには、ちょっと下準備を頑張る必要がありますね。 ただ、これらを勉強しなくても、フィーリングでなんとかいけるんじゃないかとも思ってしまいます。

  •  他にも、SQL で出てくる命令はあるので、それに対応した LINQ の命令があるのですが、ここでは扱いません。 LINQ は分かってしまえば簡単なものです。それに、DB だけじゃなくて、コレクションデータや XML など、いろんなジャンルのデータに対して使えます。 タイピングが楽になり、保守しやすくなるのであれば、覚えなければ損ですよ。

  •  最後までこの記事を読んでいただき、ありがとうございました。

  • スポンサーリンク