Help us understand the problem. What is going on with this article?

VB.NETでLINQのグループ化

More than 1 year has passed since last update.

環境

  • VB.NET
  • .NET Framework 4.6

VB.NETでLINQのグループ化(SUM)

VB.NETでGroupByのLINQの書き方を調べても全然ヒットしないので覚書。
特にメソッドのLINQは少ないので困る。

難しい話は置いておいて結論から先に、複数キーでグループ化するには、

  • New WithじゃなくてTuple.Createを使用する。
Dim group = details.GroupBy(Function(g) Tuple.Create(g.Item, g.category))
  • New WithならKeyを付ける
Dim group = details.GroupBy(Function(g) new with{ Key g.Item, Key g.category})

テストで使用したリストの型

Item,Category,Quantityをもつリストを作成して、
Item,Categoryをグループ化、Quantityを合計する。

リストは以下の型クラス。

    Class Items

        Public Property Item As String
        Public Property category As String
        Public Property Quantity As Integer

        Public Sub New(item As String, category As String, quantity As Integer)
            Me.Item = item
            Me.category = category
            Me.Quantity = quantity
        End Sub

    End Class

匿名型でGroupByをしてみる

ネットで漁ってC#例からVB.NETに書き換えてみた。
Hogehoge()すると一応LINQは動くのだけど、期待通りの結果にならない。

    Public Sub Hogehoge()

        Dim details As New List(Of Items)
        details.Add(New Items("A", "CateA", 1))
        details.Add(New Items("A", "CateA", 2))
        details.Add(New Items("B", "CateB", 1))

        Dim group = details.GroupBy(Function(g) New With(g.Item, g.category)).
            Select(Function(x) New With {.groupItem = x.Key.Item1, .groupCategory = x.Key.Item2, .sumQuantity = x.Sum(Function(s) s.Quantity)}).
            ToList

        For Each item In group
            Debug.WriteLine(item.groupItem & ", " & item.groupCategory & ", " & item.sumQuantity)
        Next

        'A, CateA, 1
        'A, CateA, 2 ' AのItemが3の1行になることを期待してた。
        'B, CateB, 1

    End Sub

Tuple.Createを使う

New Withの代わりにTuple.Createを使用すると期待通り。

    Public Sub Hogehoge()

        Dim details As New List(Of Items)
        details.Add(New Items("A", "CateA", 1))
        details.Add(New Items("A", "CateA", 2))
        details.Add(New Items("B", "CateB", 1))

        Dim group = details.GroupBy(Function(g) Tuple.Create(g.Item, g.category)).
            Select(Function(x) New With {.groupItem = x.Key.Item1, .groupCategory = x.Key.Item2, .sumQuantity = x.Sum(Function(s) s.Quantity)}).
            ToList

        For Each item In group
            Debug.WriteLine(item.groupItem & ", " & item.groupCategory & ", " & item.sumQuantity)
        Next

        ' A, CateA, 3 ' 期待通りの動作!
        ' B, CateB, 1

    End Sub

Keyを付ける

匿名型にKeyをつけると期待通り。

    Public Sub Hogehoge()

        Dim details As New List(Of Items)
        details.Add(New Items("A", "CateA", 1))
        details.Add(New Items("A", "CateA", 2))
        details.Add(New Items("B", "CateB", 1))

        Dim group = details.GroupBy(Function(g) New With(Key g.Item, Key g.category)).
            Select(Function(x) New With {.groupItem = x.Key.Item1, .groupCategory = x.Key.Item2, .sumQuantity = x.Sum(Function(s) s.Quantity)}).
            ToList

        For Each item In group
            Debug.WriteLine(item.groupItem & ", " & item.groupCategory & ", " & item.sumQuantity)
        Next

        ' A, CateA, 3 ' 期待通りの動作!
        ' B, CateB, 1

    End Sub

感想

  • 頑張ってC#から変換しても思うように行かなかった。
  • 自分のような.Net初心者はC#とVBの匿名型の挙動が違うので知らないと積む。
  • 他にやり方がありそう。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした