2016-06-15 2 views
1

Я имеюбыстрый способ для поиска строки в большой CSV-файл C#

  • DataTable (столбцы AccId и TerrName), который содержит более 2000 строк.
  • большой файл csv (столбцы AccId и External_ID), содержащие более 6 миллионов записей.

Теперь мне нужно сопоставить AccId и найти его соответствующий External_ID из файла csv.

В настоящее время я его достижения, используя ниже код:

DataTable tblATL = Util.GetTable("ATL", false); 
tblATL.Columns.Add("External_ID"); 

DataTable tbl = Util.CsvToTable("TT.csv", true); 

foreach (DataRow columnRow in tblATL.Rows) 
{ 
    var query = tbl.Rows.Cast<DataRow>().FirstOrDefault(x => x.Field<string>("AccId") == columnRow["AccId"].ToString()); 
    if (query != null) 
    { 
     columnRow["External_ID"] = query.Field<string>("External_ID"); 
    } 
    else 
    { 
     columnRow["External_ID"] = "New"; 
    } 
} 

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

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

+0

Можете ли вы привести примеры заголовков файла csv? например, имена полей, их порядок/тип и т. д. (хранение записей 6M в памяти всегда будет медленнее) – BugFinder

+0

Если вы загружаете весь файл csv в память, PLinq всегда является опцией. – Sidewinder94

+0

@BugFinder: все столбцы имеют строковый тип без определенного порядка. AccId, External_ID 001P000000eHknBIAS, 303363IN 001U000001bU0Q6IAK, 303063IN – Avijit

ответ

3

Предлагаю организовать данные в словаре , скажем, Dictionary<String, String[]>, который имеет O(1) сложность времени, например.

Dictionary<String, String[]> Externals = File 
    .ReadLines(@"C:\MyFile.csv") 
    .Select(line => line.Split(',')) // the simplest, just to show the idea 
    .ToDictionary(
     items => items[0], // let External_ID be the 1st column 
     items => items // or whatever record representation 
    ); 

    .... 

    String externalId = ... 

    String[] items = Externals[externalId]; 

EDIT: если же External_ID может оказаться более , чем когда-то (см комментарии ниже) вы должны иметь дело с дубликатами, например

var csv = File 
    .ReadLines(@"C:\MyFile.csv") 
    .Select(line => line.Split(',')) // the simplest, just to show the idea 

Dictionary<String, String[]> Externals = new Dictionary<String, String[]>(); 

foreach (var items in csv) { 
    var key = items[0]; // let External_ID be the 1st column 
    var value = items; // or whatever record representation 

    if (!Externals.ContainsKey(key)) 
    Externals.Add(key, value); 
    // else { 
    // //TODO: implement, if you want to deal with duplicates in some other way 
    //} 
} 
+0

Позвольте мне реализовать его. – Avijit

+0

В настоящее время я сталкиваюсь с проблемой с данными, файл может содержать дубликат AccId с различными External_Id, необходимо учитывать первое его появление. Исключение словаря для исключения из-за дублирования ключа, как и ожидалось. – Avijit

+0

@Avijit: в этом случае вам придется иметь дело с дубликатами (см. Мое редактирование) и простейшим 'ToDictionary()' не будет. –

Смежные вопросы