Использование Linq для обработки набора данных объектов - PullRequest
0 голосов
/ 26 мая 2011

У меня есть коллекция (IList (Of Sample)) следующего класса:

Public Class Sample
    Public sampleNum As String
    Public volume As Integer
    Public initial As Single
    Public final As Single
End Class

Эта коллекция заполнена регулярным выражением, которое передается по файлу.

Что явы хотите использовать Linq, чтобы сгенерировать их для каждого уникального образца, используя следующие условия:

Для каждого образца:

  1. Максимальный объем, при котором конечный результат больше, чемодин
    • Если в образце есть несколько записей для этого тома, выберите запись с наивысшим итоговым значением
  2. Если предыдущий шаг оставляет нас без записей, выберите запись смаксимальный финальный объем игнорирования

Я чрезвычайно новичок в Linq и просто не могу разобраться с этим.На данный момент я решил эту проблему с помощью каждого и временных списков, но меня интересует, как это будет обрабатываться с использованием чистого Linq.

Пример данных:

samplenum | volume | initial | final
1         | 50     | 8.47    | 6.87
1         | 300    | 8.93    | 3.15
2         | 5      | 8.28    | 6.48
2         | 10     | 8.18    | 5.63
2         | 5      | 8.33    | 6.63
2         | 10     | 8.26    | 5.58
3         | 1      | 8.31    | 0.75
3         | 5      | 8.19    | 0.03
4         | 50     | 8.28    | 6.55
4         | 300    | 7.19    | 0.03

Ответы [ 2 ]

1 голос
/ 27 мая 2011

Надеемся, это решит ваши проблемы:

    Dim source As IEnumerable(Of Sample)

    ' Get the data... 

    Dim processed = source _
                    .GroupBy(Function(s) s.sampleNum) _
                    .Select(Function(s) Process(s))

    Dim array = processed.ToArray()
    Console.ReadLine()

Функция процесса:

Private Function Process(ByVal sequence As IEnumerable(Of Sample)) As Sample 
    Dim filtered = (
        From s In sequence
        Where s.final > 1
        Order By
            s.volume Descending,
            s.final Descending
        )

    ' If we don't have any elements after the filtering, 
    ' return the one with the highest final.
    ' Otherwise, return the first element.
    If Not filtered.Any() Then
        Return (From s In sequence Order By s.final Descending).FirstOrDefault()
    Else
        Return filtered.First()
    End If

End Function
1 голос
/ 26 мая 2011

Попробуй это. Я не пробовал, но он должен делать то, что вы хотите. Есть пробники лучший способ сделать это:

    ' For each sample number in the list
    For Each el In (From p In lst Select p.sampleNum).Distinct()
        ' can cause odd results in some cases so always put the foreach var into another var
        Dim var As String = el
        ' get another "list" but for this sample num
        Dim res As IEnumerable(Of Sample) = lst.Where(Function(p) p.volume > 1 AndAlso p.sampleNum = var)
        Dim sam As Sample ' the result
        If Not res Is Nothing And res.Any() Then
            ' we have a result, so get the first result where the 
            sam = res.Where(Function(p) p.volume = res.Max(Function(x) x.volume)).First()
        Else
            ' we have no results, so resort back to the normal list, for this sample number
            sam = lst.Where(Function(p) p.sampleNum = var AndAlso p.volume = lst.Max(Function(x) x.volume)).First()
        End If
        '
        ' do what ever with the sample here
        '
    Next
...