如何最优筛选DataTable行?获取最大值对应DataRows的高效方法
从DataTable中高效获取含最大值列的DataRow的最优方法
需求说明
我需要从包含多列的DataTable中,获取某整数列值为最大值的所有DataRow,想找到最简且最高效的实现方式。当前我用以下代码实现:
Dim maxValue = 0 For Each row In mDataTable.Rows If row.valueCell > maxValue Then maxValue = row.valueCell End If Next Dim mDataTableBis = mDataTable.Clone For Each row In mDataTable.Select("value = " & valueCell) mDataTableBis.ImportRow(row) Next
原始DataTable示例:
| Rows | letters | value |
|---|---|---|
| row 1 (需要的行) | x | 4 |
| row 2 | y | 2 |
| row 3 (需要的行) | z | 4 |
优化方案
1. 一次遍历完成(最高效)
原代码需要遍历两次DataTable,一次找最大值、一次筛选行。可以合并为一次遍历,同时记录最大值和目标行,减少IO开销:
Dim maxValue As Integer = Integer.MinValue Dim targetRows As New List(Of DataRow) For Each row As DataRow In mDataTable.Rows Dim currentValue As Integer = CInt(row("value")) If currentValue > maxValue Then maxValue = currentValue targetRows.Clear() targetRows.Add(row) ElseIf currentValue = maxValue Then targetRows.Add(row) End If Next Dim mDataTableBis = mDataTable.Clone() For Each row In targetRows mDataTableBis.ImportRow(row) Next
数据量越大,这种单遍历方式的效率优势越明显。
2. LINQ to DataSet(代码最简洁)
如果追求代码可读性和简洁度,可以用LINQ实现,无需手动写循环:
Imports System.Linq ' 先获取目标列的最大值 Dim maxValue = mDataTable.AsEnumerable().Max(Function(r) r.Field(Of Integer)("value")) ' 筛选出所有值等于最大值的行并复制到新表 Dim mDataTableBis = mDataTable.AsEnumerable().Where(Function(r) r.Field(Of Integer)("value") = maxValue).CopyToDataTable()
注意:若原DataTable为空,Max方法会抛出异常,需先判断表是否有数据;同时要引用System.Data.DataSetExtensions程序集。
3. 修正原有代码的变量错误
原代码中Select语句存在变量名错误(用了未定义的valueCell),修正后可正常运行,但仍需两次遍历:
Dim maxValue = 0 For Each row In mDataTable.Rows If CInt(row("value")) > maxValue Then maxValue = CInt(row("value")) End If Next Dim mDataTableBis = mDataTable.Clone For Each row In mDataTable.Select($"value = {maxValue}") mDataTableBis.ImportRow(row) Next
内容的提问来源于stack exchange,提问作者Kyuu
相关产品推荐
相关产品推荐

