Я ищу самый простой и быстрый способ получить DataRows из DataTable. Эти DataRows имеют несколько столбцов, в том числе один с целым числом, и мне нужны только строки с наибольшим значением.
В настоящее время я получаю этот результат следующим образом:
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
Исходная таблица данных (например):
Привет, добро пожаловать в StackOverflow. Пожалуйста, прочитайте начало тура и как спросить. Код, который вы разместили, недействителен, пожалуйста, покажите, что вы пробовали и где у вас возникли проблемы.
Если вы предпочитаете цикл для каждого цикла, как видно из кода, который вы разместили, используйте эту функцию:
Public Sub ForEachLoop()
Dim maxValue As Integer
' Loop through rows to find max value
For Each row As DataRow In mDataTable.Rows
Dim currentRowValue As Integer = row.Field(Of Integer)(numbersColumn)
If currentRowValue > maxValue Then
maxValue = currentRowValue
End If
Next
' Create a List of DataRow
Dim res As New List(Of DataRow)
' Loop through rows again to add to list each row in which numbersColumn field = maxValue
For Each row As DataRow In mDataTable.Rows
If row.Field(Of Integer)(numbersColumn) = maxValue Then
res.Add(row)
End If
Next
' Create results DataTable copying the List to a new DataTable
Dim result As DataTable = res.CopyToDataTable()
End Sub
Если вам нужно что-то более лаконичное, вы можете попробовать LINQ, но это более продвинутое решение, конечно, не удобное для новичков.
Что-то вроде:
Public Sub LINQ()
' Find the row with highest value in numbersColumn, then get the value from the field
Dim maxValue As Integer = mDataTable.AsEnumerable().MaxBy(Function(x) x.Field(Of Integer)(numbersColumn)).Field(Of Integer)(numbersColumn)
' Select all the rows with numbersColumn value = maxValue (this returns an IEnumerable of DataRow)
Dim resultsRows As IEnumerable(Of DataRow) = mDataTable.AsEnumerable().Where(Function(x) x.Field(Of Integer)(numbersColumn) = maxValue)
' Create results DataTable copying the IEnumerable to a new DataTable
Dim result As DataTable = resultsRows.CopyToDataTable()
End Sub
Вы также можете использовать метод DataTable.Select()
...
Public Sub DataTableSelect()
Dim result As DataTable = mDataTable.Select("numbersColumn = max(numbersColumn)").CopyToDataTable()
End Sub
... но это значительно медленнее, чем для каждого цикла:
Как видите, для каждой версии примерно в 3500 раз быстрее, чем для версии Select()
— это большая разница!
Этот тест был выполнен на относительно небольшой таблице данных с примерно 10 000 строк — представьте, насколько большой может быть разница в таблице данных с миллионом строк.
Спасибо, именно такие ответы я и искал. Вы мне очень помогли, особенно при сравнении времени выполнения по методу. Почему метод DataTable.Select() такой медленный?
@QuentinL Рад, что мой ответ помог вам! DataTable.Select() должен выполнять дополнительные задачи по сравнению с методами LINQ или для каждого цикла — он должен анализировать текст запроса и, возможно, должен создавать внутренний индекс и другой служебный код. Я действительно хотел бы ответить на этот вопрос более подробно, но у меня недостаточно опыта, чтобы объяснить, как на самом деле работает метод Select() внутренне - надеюсь, какой-нибудь опытный программист сможет добавить лучшее объяснение этой огромной разницы в производительности. Кстати, метод Select() обычно считается плохой практикой, используйте его, только если у вас действительно нет альтернатив.
@QuentinL Я забыл упомянуть (я отредактировал ответ несколько секунд назад): мой тест был выполнен для таблицы данных из 10 тыс. строк; если вы можете сказать мне, сколько строк в вашей DataTable, я буду рад снова запустить тест.
@PrivateFranck Моя таблица имеет длину от 10 до 100 тысяч строк, поэтому проведенные вами тесты соответствуют размеру моей таблицы (довольно маленькой). Ваши объяснения метода DataTable.Select() теперь имеют смысл.
Пожалуйста, уточните вашу конкретную проблему или предоставьте дополнительную информацию, чтобы выделить именно то, что вам нужно. Как сейчас написано, трудно точно сказать, о чем вы спрашиваете.