1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Visual BasicAdvent Calendar 2024

Day 14

【VB.NET】.NET 9でLINQに追加されたメソッドを使ってみる

Last updated at Posted at 2024-12-14

はじめに

これは、Visual Basic Advent Calendar 2024の14日目の記事となります。

11月13日に「.NET 9.0」 がリリースされました。
VB.NETは新機能の対応はしない方針ではあるが、記法に関係ない部分は対応します。

.NET 9.0でLINQに追加されたメソッド

.NET 9でLINQに追加された各メソッドCountByAggregateByIndexができるか確認してみました。

サンプルが分かりにくかったので下記サイトを参考に変更してみました。

共通モジュール

Public Class Person
    Public FirstName As String
    Public LastName As String
    Public Point As Integer
End Class

Sub Main(args As String())
    Dim people As New List(Of Person) From {
        New Person With {.FirstName = "鈴木", .LastName = "一郎", .Point = 78},
        New Person With {.FirstName = "鈴木", .LastName = "花子", .Point = 92},
        New Person With {.FirstName = "山田", .LastName = "太郎", .Point = 85},
        New Person With {.FirstName = "佐藤", .LastName = "健太", .Point = 95},
        New Person With {.FirstName = "佐藤", .LastName = "美咲", .Point = 88}
    }

CountBy

CountByメソッドは、グループ分けしてグループごとの個数を求めるメソッドです。

For Each sameFirstName In people.CountBy(Function(p) p.FirstName)
    Console.WriteLine($"同じ苗字が {sameFirstName} 人、{sameFirstName}")
Next

結果

同じ苗字が 2 人、鈴木
同じ苗字が 1 人、山田
同じ苗字が 2 人、佐藤

AggregateBy

AggregateByはGroupByとAggregateを合体させたようなメソッドです。グルーピングしつつ、グループごとにアグリゲーション(まとめる、集計)メソッドです。

Dim aggregateBy = people.AggregateBy(Function(p) p.Point \ 10, Function(x) 0, Function(x, y) x + y.Point)
For Each kvp In aggregateBy
    Console.WriteLine($"同一ポイント {kvp.Key * 10}点台 の集計結果 {kvp.Value}")
Next

結果

同一ポイント 70点台 の集計結果 78
同一ポイント 90点台 の集計結果 187
同一ポイント 80点台 の集計結果 173

Index

Indexメソッドは各要素をインデックスと合わせてタプルにした返すメソッドです。

For Each p In people.Index()
    Console.WriteLine($"エントリー {p.Index + 1}: : Person {{ FirstName = {p.Item.FirstName}, LastName = {p.Item.LastName}, Point = {p.Item.Point} }}")
Next

Selectのオーバーロードを利用して同じことができる。

For Each item In people.Select(Function(Value, Index) New With {Value, Index})
    Console.WriteLine($"エントリー {item.Index + 1}: Person {{ FirstName = {item.Value.FirstName}, LastName = {item.Value.LastName}, Point = {item.Value.Point} }}")
Next

結果

エントリー 1: Person { FirstName = 鈴木, LastName = 一郎, Point = 78 }
エントリー 2: Person { FirstName = 鈴木, LastName = 花子, Point = 92 }
エントリー 3: Person { FirstName = 山田, LastName = 太郎, Point = 85 }
エントリー 4: Person { FirstName = 佐藤, LastName = 健太, Point = 95 }
エントリー 5: Person { FirstName = 佐藤, LastName = 美咲, Point = 88 }

その他

LINQ以外でもOrderedDictionaryが追加されています。

OrderedDictionary

OrderedDictionaryクラスは順序を保証します。

Swift版のDictionaryクラスのように直ぐ順序に変更されるなら分かるのですが…

.NET版の通常のDictionaryクラスは順序を保証しない実装ですが、結構一致します。

' インスタンス作成
Dim dict As New OrderedDictionary(Of String, Integer) From {
    {"A", 1},
    {"B", 2},
    {"C", 3}
}

' キーと要素を追加
dict.Add("D", 4)

' キーに紐づく要素を削除
dict.Remove("D")

' キーと要素を追加
dict.Add("E", 5)

' キーに紐づく要素を検索し、見つかった場合には要素を取得する
Dim value As Integer
If dict.TryGetValue("A", value) Then
    Console.WriteLine(value) ' 1
End If

' 保持しているキーと要素を列挙する
' 追加した順番(登録した順番)で列挙する
For Each pair In dict
    Console.WriteLine($"key = {pair.Key}, Value = {pair.Value}")
Next

結果

1
key = A, Value = 1
key = B, Value = 2
key = C, Value = 3
key = E, Value = 5

最後に

C# で作成して、ChatGPTでVB.NET に変換してみたんですが、まだちゃんとした対応されていないようで変な変換をしてしまう。
よって、ちゃんと理解した上で記事を修正しました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?