この記事は VB.NET で開発をしているのに、まだ LINQ(リンク)が使えていない私が
こちらの記事で LINQ を勉強したとき作成したソースコードになります。
はじめての LINQ
https://qiita.com/nskydiving/items/c9c47c1e48ea365f8995
※ソースコードのみとなりますのでオリジナルの記事とあわせてご覧ください。
LINQ をはじめる前に
・クエリ構文とメソッド構文
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' クエリ構文
Dim query = From x In list
Where x Mod 2 = 0
Order By x
Select x * 3
'' メソッド構文(この記事ではこちらを採用)
Dim query = list _
.Where(Function(x) x Mod 2 = 0) _
.OrderBy(Function(x) x) _
.Select(Function(x) x * 3)
・型推論
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'Dim list As List(Of Integer) = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6}) '' VB.NET 9.0 以前の書き方
For Each x In list
Console.WriteLine(x)
Next
・匿名クラス
Dim fruitList = {
New With {.Name = "りんご", .Price = 300},
New With {.Name = "バナナ", .Price = 200},
New With {.Name = "パイナップル", .Price = 1000},
New With {.Name = "いちご", .Price = 500}
}
For Each fruit In fruitList
Console.WriteLine(fruit)
Next
・ラムダ式
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' list の要素から偶数を取り出す
Dim findAllList = list.FindAll(Function(x) x Mod 2 = 0)
Console.WriteLine("=== findAllList ===")
For Each x In findAllList
Console.WriteLine(x)
Next
'' list の要素をそれぞれ 3 倍にする
Dim convertAllList = list.ConvertAll(Function(x) x * 3)
Console.WriteLine("=== convertAllList ===")
For Each x In convertAllList
Console.WriteLine(x)
Next
'' VB.NETは匿名メソッドがないので省略
LINQ の使い方
・要素の取得
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' list の最初の要素を取得する
Console.WriteLine("First: " + list.First().ToString)
'' list の最後の要素を取得する
Console.WriteLine("Last: " + list.Last().ToString)
・集計
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' list の最大値を取得
Console.WriteLine("Max: " + list.Max().ToString)
'' list の最小値を取得
Console.WriteLine("Min: " + list.Min().ToString)
'' list の平均値を取得
Console.WriteLine("Average: " + list.Average().ToString)
'' list の合計値を取得
Console.WriteLine("Sum: " + list.Sum().ToString)
'' list の要素値を取得
Console.WriteLine("Count: " + list.Count().ToString)
・変換
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' list を配列に変換
Dim array As Integer() = list.ToArray()
Console.WriteLine("=== array ===")
For Each x In array
Console.WriteLine(x)
Next
'' list を object 型の List に変換
Dim objectList As List(Of Object) = list.Cast(Of Object)().ToList()
Console.WriteLine("=== objectList ===")
For Each x In objectList
Console.WriteLine(x)
Next
・複数要素の取得
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' list から重複を除いた要素を取得する
Dim distinctList = list.Distinct()
Console.WriteLine("=== distinctList ===")
For Each x In distinctList
Console.WriteLine(x)
Next
'' list の先頭から指定された数の要素をスキップして残りの要素を取得する
Dim skipList = list.Skip(3)
Console.WriteLine("=== skipList ===")
For Each x In skipList
Console.WriteLine(x)
Next
'' list の先頭から指定された数の要素を取得する
Dim takeList = list.Take(3)
Console.WriteLine("=== takeList ===")
For Each x In takeList
Console.WriteLine(x)
Next
・判定
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' list のすべての要素が 100 未満かどうか
Console.WriteLine("All: " + list.All(Function(x) x < 100).ToString)
'' list のいずれかの要素が 0 未満かどうか
Console.WriteLine("Any: " + list.Any(Function(x) x < 0).ToString)
'' list に値が 40 の要素が含まれてるかどうか
Console.WriteLine("Contains: " + list.Contains(40).ToString)
・集合
Dim list1 = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
Dim list2 = New List(Of Integer)(New Integer() {1, 16, 39, 33, 7, 84})
'' 和集合を取得する
Dim unionList = list1.Union(list2)
Console.WriteLine("=== unionList ===")
For Each x In unionList
Console.WriteLine(x)
Next
'' 差集合を取得する
Dim exceptList = list1.Except(list2)
Console.WriteLine("=== exceptList ===")
For Each x In exceptList
Console.WriteLine(x)
Next
'' 積集合を取得する
Dim intersectList = list1.Intersect(list2)
Console.WriteLine("=== intersectList ===")
For Each x In intersectList
Console.WriteLine(x)
Next
・ソート
Dim fruitList = {
New With {.Name = "りんご", .Price = 300},
New With {.Name = "バナナ", .Price = 200},
New With {.Name = "パイナップル", .Price = 1000},
New With {.Name = "いちご", .Price = 500}
}
'' fruitList を Price が昇順になるように並び替える
Dim orderByList = fruitList.OrderBy(Function(x) x.Price)
Console.WriteLine("=== orderByList ===")
For Each x In orderByList
Console.WriteLine(x)
Next
'' fruitList を Price が降順になるように並び替える
Dim orderByDescendingList = fruitList.OrderByDescending(Function(x) x.Price)
Console.WriteLine("=== orderByDescendingList ===")
For Each x In orderByDescendingList
Console.WriteLine(x)
Next
'' fruitList を逆順に並び替える
Dim reverseList = fruitList.Reverse()
Console.WriteLine("=== reverseList ===")
For Each x In reverseList
Console.WriteLine(x)
Next
・LINQ メソッドの組み合わせ
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' LINQ メソッドを組み合わせて使う
'' 重複要素を削除、先頭から指定された数の要素をスキップ、昇順に並び替え
Dim resultList1 = list _
.Distinct() _
.Skip(2) _
.OrderBy(Function(x) x)
Console.WriteLine("=== resultList1 ===")
For Each x In resultList1
Console.WriteLine(x)
Next
'' LINQ 以外のメソッド(FindAll、ConvertAll)も組み合わせて使う
'' ConvertAll メソッドを使用するため一旦 List に変換する
Dim resultList2 = list _
.FindAll(Function(x) x Mod 2 = 0) _
.OrderBy(Function(x) x) _
.ToList() _
.ConvertAll(Function(x) x * 3)
Console.WriteLine("=== resultList2 ===")
For Each x In resultList2
Console.WriteLine(x)
Next
Select と Where
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' LINQ 以外のメソッド(FindAll、ConvertAll)も組み合わせて使う
'' ConvertAll メソッドを使用するため一旦 List に変換する
Dim resultList1 = list _
.FindAll(Function(x) x Mod 2 = 0) _
.OrderBy(Function(x) x) _
.ToList() _
.ConvertAll(Function(x) x * 3)
Console.WriteLine("=== resultList1 ===")
For Each x In resultList1
Console.WriteLine(x)
Next
'' FindAll メソッドを Where メソッドに、ConvertAll メソッドを Select メソッドに書き換え(処理は同じ)
Dim resultList2 = list _
.Where(Function(x) x Mod 2 = 0) _
.OrderBy(Function(x) x) _
.Select(Function(x) x * 3)
Console.WriteLine("=== resultList2 ===")
For Each x In resultList2
Console.WriteLine(x)
Next
'' クエリ構文で書き換え(処理は同じ)
'' (実は最初に紹介した「LINQ の典型的な例」と同じ)
Dim resultList3 =
From x In list
Where x Mod 2 = 0
Order By x
Select x * 3
Console.WriteLine("=== resultList3 ===")
For Each x In resultList3
Console.WriteLine(x)
Next
LINQ のメリット
・少ない行数、ネスト数で簡潔なコードが書ける
Dim list = New List(Of Integer)(New Integer() {1, 84, 95, 95, 40, 6})
'' LINQ を使って実装
'' ========================================
Dim resultList1 = list _
.Where(Function(x) x Mod 2 = 0) _
.OrderBy(Function(x) x) _
.Select(Function(x) x * 3)
Console.WriteLine("=== resultList1 ===")
For Each x In resultList1
Console.WriteLine(x)
Next
'' ========================================
'' LINQ は使わず、For Each と For を使って実装
'' ========================================
Dim resultList2 = New List(Of Integer)
For Each x In list
If x Mod 2 = 0 Then
resultList2.Add(x)
End If
Next
resultList2.Sort(Function(x, y) x.CompareTo(y))
For i As Integer = 0 To resultList2.Count() - 1
resultList2(i) *= 3
Next
Console.WriteLine("=== resultList2 ===")
For Each x In resultList2
Console.WriteLine(x)
Next
'' ========================================
感想
食わず嫌いしていましたが、
オリジナルの記事を参考に勉強したら驚くほどすんなり覚えることができました。感謝です!
クエリ構文とメソッド構文はどっちがいいのかな?とか考えていましたが
記事はほとんどメソッド構文で書かれていますが、終わってみたらクエリ構文も書けるようになっていました。