使用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生成一个集合,使用以下条件。

对于每个样本数量:

  1. 在决赛大于1的地方拥有最高的音量
    • 若样本有多个该卷的记录,则选择最终记录最高的一个
  2. 如果上一步没有记录,请选择最终忽略音量最高的记录

我是林克的新手,我就是无法理解这一点。目前,我已经使用For each和临时列表解决了这个问题,但我对如何使用纯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

相关内容

  • 没有找到相关文章

最新更新