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

时间:2011-05-26 15:27:54

标签: vb.net linq linq-to-objects

我有以下类的集合(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生成这些的集合。

对于每个样本:

  1. 具有最高音量,其中最终音量大于1
    • 如果样本有多个此卷的记录,则选择具有最高最终
    • 的记录
  2. 如果上一步离开我们没有记录,则选择具有最高最终忽略量的记录
  3. 我对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 个答案:

答案 0 :(得分:1)

试试这个。我没有尝试过,但它应该做你想要的。有一种更好的方法:

    ' 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

答案 1 :(得分:1)

这应该有希望解决你的问题:

    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