VB Linq GroupBy Min

#vb.net #linq #min

#vb.net #linq #минимум

Вопрос:

Я хочу только минимальный срок для каждой программы и возвращать новый список выбранных программ с помощью 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 amp; "---" amp; g.Key.ToString)
            Console.WriteLine()
        Next
     
    End Sub
 

Ответ №1:

Если я все правильно понял, вам нужен выбор (фильтр) существующего List(Of ProgramSelection) , где term минимальное значение и возвращать только отфильтрованные элементы в списке как новые List(Of ProgramSelection) .

Вы можете GroupBy() , как вы делаете, затем для каждой группировки получить Min() значение term свойства и создать новый элемент ProgramSelection с ключом группировки и найденным минимальным значением. Что-то вроде этого:

 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()
 

Другой метод, использующий Select() для получения группировок и OrderBy().First() фильтрации выборки на основе минимального значения свойства term, преобразуемого — в данном случае — в целочисленное значение (я не уверен, что это возможно в реальном классе. В случае, если у вас есть все номера там):

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

ИМО, term свойство должно быть целым числом. Использование строки может работать в любом случае, но поскольку вам нужно минимальное значение… Если минимальный означает что-то другое, добавьте специфику.

Комментарии:

1. Можно ли то же самое сделать с помощью только a . Предложение Where вместо возврата нового выбора программы?

2. Посмотрите редактирование, может быть, этого достаточно для того, что вы хотите сделать.

Ответ №2:

Сгруппируйте сбор по программам и «выберите» только минимальный срок.

 Dim result = programs.GroupBy(Function(p) p.program).
    Select(Function(group) $"{group.Key}---{g.Min(Function(p) p.term)}")

For Each item in result
    Console.WriteLine(item)
Next
 

Основываясь на значениях .term свойства, вам, вероятно, потребуется преобразовать их в корректно сопоставимый тип DateTime или Integer до нахождения минимального значения.

 Dim result = programs.GroupBy(Function(p) p.program).
    Select(Function(group)
      Return New ProgramSelection With
      {
        .program = group.Key,
        .term = group.Select(Function(p) Integer.Parse(p.term)).Min().ToString()
      }
    End Function)

For Each program in result
    Console.WriteLine($"{p.program}---{p.term}")
Next