#vb.net
#vb.net
Вопрос:
У меня есть файл csv, содержащий, скажем, 50 столбцов. не всегда бывает так, что все эти имена столбцов уникальны.таким образом, преобразование этого в таблицу данных иногда невозможно напрямую.
итак, моя идея ,
- игнорируйте имена столбцов и читайте csv
- получаем первую строку (которая на самом деле является именами столбцов).
- преобразуйте его в список строк.
- найдите дубликаты из этого списка. допустим, у меня есть 5 дубликатов
ниже приведен алгоритм, который будет выполнять эту работу, до этого counter shuld be -1
for all dupe in duplicate items
{
for all str in string array
{
if (str is eq to dupe)
counter = counter 1
if counter > 0
str = str counter
}
}
Теперь запишите обратно в строку csv (0) с новым строковым массивом.
затем измените имена столбцов таблицы данных на строку (0) и теперь удалите первую строку.
я знаю, что это чрезвычайно неэффективно. может ли кто-нибудь предложить лучший способ?
Комментарии:
1. «Крайне неэффективно» зависит от контекста; что-то подобное, похожее на одноразовую процедуру, вероятно, может выдержать некоторую неэффективность без существенного влияния на вашего конечного пользователя. Однако, если вы хотите улучшить его, я бы предложил использовать a
Dictionary(Of String, Integer)
для сопоставления дублированных имен столбцов с текущим количеством. Тогда вы могли бы запустить только внутренний цикл.2. Если вы хотите использовать его в code-golf, вы даже можете составить выражение Linq, которое преобразует заголовки столбцов за один раз, но я бы этого избегал, потому что это, вероятно, будет близко к коду только для записи.
3. вы хотите сказать, что эффективность выражений LINQ такая же, как и код, который мы пишем?
4. Иногда лучше, иногда хуже, это зависит от того, что вы с ними делаете. Их стоит делать, когда они делают ваш код более понятным и простым в обслуживании. Их не стоит делать, когда они усложняют ваш код или когда профилирование показывает, что они являются узким местом в производительности.
Ответ №1:
Вместо того, чтобы пытаться найти повторяющиеся имена столбцов, просто назначьте номер в конце каждого имени поля. Я использовал TextFieldParser
класс. Доступно в пространстве имен: Microsoft.VisualBasic.FileIO Посмотреть https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.fileio.textfieldparser?view=netcore-3.1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim TFP As New TextFieldParser("C:UsersmaryoDesktopTestCSV.csv")
TFP.Delimiters = {","}
Dim FieldNames = TFP.ReadFields
For i = 0 To FieldNames.Length - 1
FieldNames(i) amp;= i.ToString
Next
Dim dt As New DataTable
For Each FieldName In FieldNames
dt.Columns.Add(FieldName)
Next
While Not TFP.EndOfData
Dim currentRow = TFP.ReadFields()
dt.Rows.Add(currentRow)
End While
DataGridView1.DataSource = dt
End Sub
Комментарии:
1. Честно говоря, это на самом деле более простое решение. я постараюсь реализовать это сегодня и закрыть эту тему. спасибо 🙂