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
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.