使用Linq进行对象数据集处理

问题描述

| 我有以下课程的集合(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在以下条件下为每个唯一的samplenum生成这些的集合。 对于每个样本数: 拥有最高的音量,而最终的则大于 如果样本具有此卷的多个记录,则选择最终记录最高的一个 如果上一步没有记录,则选择最终忽略量最大的记录 我对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
    

解决方法

这有望解决您的问题:
    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
    ,尝试这个。我没有尝试过,但是它应该做您想要的。有一个更好的方法可以做到这一点:
    \' 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