我有以下类的集合(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的地方拥有最高的音量
- 若样本有多个该卷的记录,则选择最终记录最高的一个
- 如果上一步没有记录,请选择最终忽略音量最高的记录
我是林克的新手,我就是无法理解这一点。目前,我已经使用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