VB.NET ラムダ式(無名関数)の基本的な使い方
VB.NET
のラムダ式(無名関数)の基本的な使い方を紹介します。
ラムダ式を利用すれば、配列やリストやデータテーブルなどをSQL
の要領で簡単に宣言的に集計できます。
記事の最後に便利な使い方の例を紹介しています。
例えば以下のデータテーブルがあるとします。
ID | NAME | PRICE |
---|---|---|
1 | りんご | 150 |
2 | ばなな | 100 |
3 | みかん | 30 |
4 | いちご | 200 |
例えばID
の最大値を取得したい場合、ラムダ式を使わない場合は以下のようにFor
文やForEach
で取得することが多いと思います。
Dim max As Integer = 0
For Each row As DataRow In dt.Rows
If CInt(row("ID")) > max Then
max = CInt(row("ID"))
End If
Next
これを、ラムダ式を使用すると以下のように実装できます。
Dim max As Integer = dt.Rows.Cast(Of DataRow).Select(Function(row) CInt(row("ID"))).Max()
DataTable
のRows
、ListBox
のListItem
、Reoeater
のRepeaterItem
など、ループ処理で回すような変数(列挙可能な変数)に対しては基本的に同じように使用できます。
まずは列挙する変数にCast(Of DataRow)
のようにCast
処理を実行します。
これはラムダ式を実行するための前準備と考えてよいです。
dt.Rows.Cast(Of DataRow) 'DataTable
lb.Rows.Cast(Of ListItem) 'ListBox
rep.Rows.Cast(Of RepeaterItem) 'Repeater
Cast
のあとに続けて、ラムダ式を指定します。
上記は以下のように書き換えることができます。
Dim max As Integer = dt.Rows.Cast(Of DataRow).Select(Function(row)
Return CInt(row("ID"))
End Function).Max()
Select
メソッドの引数にファンクションを指定します。
DataRow
が1行づつパラメータとしてセットされ、ファンクションがDataRow
の件数分実行されます。
ファンクションのReturn
値(戻り値)がそれぞれのDataRow
の結果となります。
上記の例だとReturn
値はID
列の値を帰しているため、結果は1,2,3,4
となります。
結果1,2,3,4
で次のメソッドMAX()
が実行されます。
MAX
は最大値を取得するメソッドなので、4
が取得できます。
最大値ではなく、結果1,2,3,4
を配列で取得したい場合はMAX()
の代わりにToArray()
を使用します。
また、リストで取得したい場合はToList()
を使用します。
以下にいろいろな便利な使用例を紹介します。
絞り込み
行(要素)の絞り込みはSQL
と同じようにWhere
を使用します。
ラムダ式のReturn
値がTrue
の要素のみ取得されます。
「PRICE
が100以上のNAME
を配列で取得する」場合は以下のようになります。(わかりやすくするため_
を使って複数行で記載しています)
Dim arr As String() = dt.Rows.Cast(Of DataRow) _
.Where(Function(row) CInt(row("PRICE")) >= 100) _
.Select(Function(row) row("NAME").ToString).ToArray()
存在チェック
存在チェックはAny
またはAll
を使用します。
Any
はラムダ式のReturn
値がTrue
の要素が1つでもある場合、Any
の結果がTrue
になります。
All
はラムダ式のReturn
値がすべてTrue
の場合、All
の結果がTrue
になります。
「NAME
が「ばなな」の行が存在するかどうか」を判定する場合は以下のようになります。
Dim result As Boolean = dt.Rows.Cast(Of DataRow) _
.Any(Function(row) row("NAME").ToString = "ばなな")
「すべての行のPRICE
が100以上かどうか」を判定する場合は以下のようになります。
Dim result As Boolean = dt.Rows.Cast(Of DataRow) _
.All(Function(row) CInt(row("PRICE")) >= 100)