21
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VB.NETでLINQのグループ化

Last updated at Posted at 2017-10-02

環境

  • 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の匿名型の挙動が違うので知らないと積む。
  • 他にやり方がありそう。
21
20
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
21
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?