Search code examples
vb.netlinqmin

VB Linq GroupBy Min


I want only the minimum term per program and to return a new list of program selections using Linq (VB).

  Public Class ProgramSelection
    Public term As String
    Public program As String
  End Class

    Sub Main(args() As string)

        Dim ps As New List(Of ProgramSelection)
        ps.Add(New ProgramSelection With {.term = "202009", .program="2803"})
        ps.Add(New ProgramSelection With {.term = "202005", .program="9002"})
        ps.Add(New ProgramSelection With {.term = "202001", .program="2803"})
       
        Dim o = ps.GroupBy(Function(p) New With {Key p.program, p.term }).ToList()
        For Each g In o
            Console.WriteLine(g.Key.program & "---" & g.Key.ToString)
            Console.WriteLine()
        Next
     
    End Sub

Solution

  • If I've got it right, you want a selection (a filter) of the existing List(Of ProgramSelection) where the term is the minimum value and return only the filtered elements in the list as a new List(Of ProgramSelection).

    You can GroupBy() as you're doing, then, for each Grouping, get the Min() value of the term property and build a new ProgramSelection element with the Grouping Key and the min value found. Something like this:

    Dim o = ps.GroupBy(Function(p) p.program).
              Select(Function(gp) New ProgramSelection() With {
                  .program = gp.Key, .term = gp.Min(Function(p) p.term)
              }).ToList()
    

    Another method, using Select() to get the groupings and OrderBy().First() to filter the selection based on the minimum value of the term property, converted - in this case - to an Integer value (I'm not sure it's possible in the real class. In case you have all numbers there):

    Dim o = ps.GroupBy(Function(p) p.program).
               Select(Function(gp) gp.OrderBy(Function(p) CInt(p.term)).First()).ToList()
    

    IMO, the term property should be an Integer. Using a string can work anyway, but since you want the minimum value... If minimum means something different, add the specifics.