Member 12561559 Ответов: 2

Как преобразовать массив в список double


Когда у пользователя есть много тысяч элементов, выбранных в DataGridView (мы говорим о сотнях тысяч или даже миллионах) В настоящее время у меня есть цикл, но он занимает слишком много времени, поэтому, вспомнив, что у меня есть отличный код, который выполняет экспорт выбранных строк в CSV из сотен тысяч/миллионов строк всего за несколько секунд, я вытащил код linq/lambada.
Немного изменив его для своих нужд, я, кажется, не могу заставить работать следующий код:

Dim SelectedList As New List(Of Long)


SelectedList = From row As DataGridViewRow In DataGridView1.Rows.Cast(Of DataGridViewRow)()
                           Select Convert.ToInt64(row.Cells("ID").Value)


Получать
Unable to cast object of type 'WhereSelectEnumerableIterator`2[System.Windows.Forms.DataGridViewRow,System.Int64]' to type 'System.Collections.Generic.List`1[System.Int64]'."

- я предполагаю, что ему не нравится управлять тем, что я пытаюсь сделать, и/или конвертировать его в Int64 - это не то, что ему нравится, даже если этот элемент является давно опробованным int32, и я получаю ту же ошибку, но относящуюся к int32. Причина, по которой я выбрал int64, заключается в том, что записи ID-значения могут выпадать из скобки int32 из-за огромного количества записей (в их десятках миллионов и восхождении).

Я думаю, что я очень близок, и это только конверсия или Cast/DirectCast, которые нуждаются в модификации, но я в тупике, или, может быть, это "глупо".

Заранее благодарю вас за любую помощь :)

Что я уже пробовал:

Поиск в Google "самый быстрый способ получить выбранные ячейки в список" не вернул то, что я хотел, и тоже не вернул "vb.net datagridview использует lambada для получения выбранных ячеек в список"

2 Ответов

Рейтинг:
4

Maciej Los

Во-первых, я полностью согласен с вами. OriginalGriff[^]. Кстати: я бы посоветовал почитать о подкачка данных[^].

Что касается сообщения об ошибке:

Unable to cast object of type 'WhereSelectEnumerableIterator`2[System.Windows.Forms.DataGridViewRow,System.Int64]' to type 'System.Collections.Generic.List`1[System.Int64]'."

Ты должен позвонить Метод ToList() [^] чтобы иметь возможность вернуть a List(Of Long)
Dim SelectedList As New List(Of Long) = (From row As DataGridViewRow In DataGridView1.Rows.Cast(Of DataGridViewRow)()
    Select Convert.ToInt64(row.Cells("ID").Value)) _
    .ToList()

'''lambda version
'Dim SelectedList As New List(Of Long) = DataGridView1.Rows.Cast(Of DataGridViewRow) _
'    .Select(Function(row) Convert.ToInt64(row.Cells("ID").Value)) _
'    .ToList()


Удачи вам!


Member 12561559

Спасибо Macej - как раз то, что мне было нужно, и я добираюсь туда (я думаю!) - наиболее высокую оценку !

Maciej Los

Всегда пожалуйста.

Richard Deeming

Ты же на самом деле не хочешь ... New там - вы создаете новый список, затем выбрасываете его и заменяете результатами запроса LINQ. :)

Dim SelectedList As List(Of Long) = ...

Richard Deeming

Вы также можете повысить производительность, предварительно выделив размер списка в соответствии с количеством строк в сетке:

Dim SelectedList As New List(Of Long)(DataGridview1.Rows.Count)
SelectedList.AddRange(DataGridView1.Rows.Cast(Of DataGridViewRow)().Select(Function(row) Convert.ToInt64(row.Cells("ID").Value)))

Maciej Los

Соглашаться.
Спасибо за ценные замечания, Ричард.

Рейтинг:
12

OriginalGriff

Ваша первая проблема заключается в том, что у вас совершенно неправильный подход.

Цитата:
Когда у пользователя есть много тысяч элементов, выбранных в DataGridView (мы говорим о сотнях тысяч или даже миллионах)
Неужели вы всерьез думаете, что любой пользователь будет добросовестно выбирать такое количество записей? Что он даже посмотрит на такое количество записей?
Что у него есть время, чтобы дождаться появления такого количества записей - а это займет значительное количество времени?

Не думайте о повышении скорости обработки - подумайте о бедном пользователе, который сталкивается с тысячами или даже миллионами строк данных и что именно вы ожидаете от него сделать с ними? Будут ли они идти "тот один, и тот один, но не тот один" для каждого ряда? или "выбрать все" и двигаться дальше? И если они собираются выбрать все из них, почему вы тратите их время и усилия, показывая так много?

А затем посмотрите на свое сообщение об ошибке: оно говорит вам, что то, что вы пытаетесь преобразовать, является общей коллекцией, а не списком. Попробовать вызов toList на сбор ...

Но преобразование его в Linq не решит вашу проблему, он просто "скрывает" цикл - он вообще не удаляет его!


Member 12561559

Бедный пользователь-это я, к сожалению, ха-ха-ха, нет серьезно, список содержит кучу файлов, которые я скопировал (18 миллионов лохов), так что да, хотя я и не просматриваю их все, мне нужно скопировать выбранный список DGV в управляемый список :)

Причина, по которой так много записей, заключается в том, что, хотя существуют различные фильтры, которые я использую, чтобы сузить количество записей, выбирая все сразу, а затем удаляя несколько, которые мне не нужны, работает идеально.

Что касается части цикла - linq в тысячу раз быстрее, чем цикл по всем выбранным строкам через a для следующего, потребовалось около 2 секунд, чтобы выбрать 171 500 значений идентификатора.

Спасибо Грифф - я знал, что это было что - то простое-Я новичок в списках (новичок в vb.net на самом деле я использую его только год и, к сожалению, у меня есть 20 лет плохих привычек vb6, чтобы избавиться от них!). Еще раз спасибо !! :)

OriginalGriff

"linq работает в тысячу раз быстрее, чем цикл по всем выбранным строкам через a для next, потребовалось около 2 секунд, чтобы выбрать 171 500 значений идентификаторов."
Нет, это не так: фактическая работа не выполняется, пока вы не используете результаты - Linq-это система отложенного выполнения, а не волшебная палочка. Во многих случаях это медленнее, чем явный цикл, потому что итератор имеет свои собственные накладные расходы, что не является тривиальным.
Все эти "от"... "код, который вы выполняете, настраивает итератор, готовый к запуску, а не фактически обрабатывает какие-либо строки. Любая обработка производится только тогда, когда вы используете информацию. Хотите доказательств? Используйте ToList для результата Linq и посмотрите, сколько времени это займет!

Взгляните на это:
https://www.codeproject.com/Tips/312312/Counting-Lines-in-a-String
И проверьте цифры в конце!