Каков оптимальный способ фильтрации строк из DataTable?

Я ищу самый простой и быстрый способ получить 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

Исходная таблица данных (например):

Ряды буквы ценить ряд 1 (разыскивается) Икс 4 ряд 2 у 2 ряд 3 (разыскивается) г 4

Пожалуйста, уточните вашу конкретную проблему или предоставьте дополнительную информацию, чтобы выделить именно то, что вам нужно. Как сейчас написано, трудно точно сказать, о чем вы спрашиваете.

Community 11.01.2023 14:19

Привет, добро пожаловать в StackOverflow. Пожалуйста, прочитайте начало тура и как спросить. Код, который вы разместили, недействителен, пожалуйста, покажите, что вы пробовали и где у вас возникли проблемы.

IFrank 11.01.2023 19:04
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы предпочитаете цикл для каждого цикла, как видно из кода, который вы разместили, используйте эту функцию:

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() такой медленный?

Kyuu 12.01.2023 11:34

@QuentinL Рад, что мой ответ помог вам! DataTable.Select() должен выполнять дополнительные задачи по сравнению с методами LINQ или для каждого цикла — он должен анализировать текст запроса и, возможно, должен создавать внутренний индекс и другой служебный код. Я действительно хотел бы ответить на этот вопрос более подробно, но у меня недостаточно опыта, чтобы объяснить, как на самом деле работает метод Select() внутренне - надеюсь, какой-нибудь опытный программист сможет добавить лучшее объяснение этой огромной разницы в производительности. Кстати, метод Select() обычно считается плохой практикой, используйте его, только если у вас действительно нет альтернатив.

IFrank 12.01.2023 12:14

@QuentinL Я забыл упомянуть (я отредактировал ответ несколько секунд назад): мой тест был выполнен для таблицы данных из 10 тыс. строк; если вы можете сказать мне, сколько строк в вашей DataTable, я буду рад снова запустить тест.

IFrank 12.01.2023 12:52

@PrivateFranck Моя таблица имеет длину от 10 до 100 тысяч строк, поэтому проведенные вами тесты соответствуют размеру моей таблицы (довольно маленькой). Ваши объяснения метода DataTable.Select() теперь имеют смысл.

Kyuu 12.01.2023 13:53

Другие вопросы по теме