2016-07-04 4 views
-3

У меня есть большой файл txt, загруженный в DataTable в программу C#.Лучшие результаты, чтобы найти значение в DataTable? Для ? Linq? Другие?

Мне нужно найти значения severasl в этой таблице данных.

На данный момент я использую простой цикл For, и он очень длинный! Мне действительно нужно выиграть время.

Есть ли лучший способ выполнить это? Использование Linq? или другой метод?

Вот основной пример моего кода:

foreach (DataRow row in DataTables[0].Rows) 
{ 
    for (int i = 0; i <= DataTables[1].Rows.Count - 1; i++) 
    { 

     if ((DataTables[1].Rows[i]["PRODUCT_CODE"].ToString().Trim() == row["PRODUCT_CODE"].ToString().Trim()) 
     { 
      // Do Some Stuff 
      // When the value is found, don't break the for...continue because there is severals "PRODUCT_CODE", not once. 
     } 
    } 
} 
+2

Вопрос в том, как структурированы ваши данные? Можете ли вы реструктурировать его лучше для более эффективного поиска? Рассуждение о том, использовать ли linq или для цикла, не имеет значения. – pijemcolu

+0

, если вы хотите найти конкретное значение только тогда, чтобы цикл был лучше после найденного значения, прервите цикл. Надеюсь, это поможет вам –

+0

DataTable.Select и это не linq, а родной метод класса. Почему вы не отправляете код, который выполняет ваш поиск сейчас? Это необходимо для понимания того, что можно оптимизировать – Steve

ответ

1

короткий пример использования более в качестве одного ядра

Parallel.ForEach(dt.AsEnumerable(), row => 
{ 
    if (i["value1"].ToString() == "test") 
    { 
     Console.WriteLine(i["value1"]); 
    } 
}); 

Другое Solution

Сравнить ключи очень быстро

Dictionary<string, Product> file1 = new Dictionary<string, Product>(); 
Dictionary<string, Product> file2 = new Dictionary<string, Product>(); 

//Add ProductCode in key 

var product = new Product(); 
product.Code = "EAN1202"; 
product.Manufacturer = "Company"; 
product.Name = "Test"; 
product.Price = 12.05; 

file1.Add(product.Code, product); 

//One thread 
foreach (var item in file1) 
{ 
    if (file2.ContainsKey(item.Key)) 
    { 
     // Do Some Stuff 
    } 
} 

//Multi thread 
Parallel.ForEach(file1, item => 
{ 
    if (file2.ContainsKey(item.Key)) 
    { 
     // Do Some Stuff 
    } 
}); 

Продукт класса

public class Product 
{ 
    public string Code; 
    public string Manufacturer; 
    public string Name; 
    public double Price; 
} 
+0

Здравствуйте, спасибо за ответ. Является ли ваш код подходящим с двумя данными? Я редактировал свои вопросы с помощью своего кода, если вам нужно это понять. Еще раз спасибо :) –

+0

Другой вопрос ... на моем «файле2».Код продукта не является первичным ключом. Существует один и тот же код продукта. И мне нужно повторить так много, как там. Будет ли это нормально с вашим кодом? –

2
HashSet<string> dt0 = new HashSet<string>(); 
foreach (DataRow row in DataTables[0].Rows) 
    dt0.Add(row["PRODUCT_CODE"].ToString().Trim()); 
for (int i = 0; i <= DataTables[1].Rows.Count - 1; i++) 
{ 
    if (dt0.Contains(DataTables[1].Rows[i]["PRODUCT_CODE"].ToString().Trim() == row["PRODUCT_CODE"].ToString().Trim()) 
    { 
     // Do Some Stuff 
     // When the value is found, don't break the for...continue because there is severals "PRODUCT_CODE", not once. 
    } 
} 

Просто пошли из О (п^т) к О (п + т)

Если вам нужен весь ряд затем словарь, а затем HashSet

Dictionary<String, DataRow> dt0 = new Dictionary<String, DataRow>(); 

Вы должны использовать HashSet/Dictionary для большего.

Я бы дал вам больше, но у вас была наглость спросить меня, могу ли я подумать, что это будет быстрее.

Почему вы используете DataTables в первую очередь?

+0

Потому что я показываю его в datagridview, более легко отлаживать как визуально! Да, мне нужен целый ряд. Считаете ли вы, что это будет действительно быстрее? –

+0

Нет, я просто потратил свое время на дикую догадку. И полностью сделал от O (n^m) до O (n + m). Ваша петля * легко *. Вы хотите скорость или легко? Потому что DataTable не самый быстрый. – Paparazzi

+0

Извините, папарацци, я бы не стал дерзостью. Мне очень жаль, и я ценю вашу помощь. –

0

Это, вероятно, может быть немного лучше, если бы мы знали, что вы делали в цикле, но это должно работать:

var dt1=DataTables[0].Rows.AsEnumerable(); 
var dt2=DataTables[1].Rows.AsEnumerable(); 
var results=dt1.Join(
    dt2, 
    d1=>d1.Field<string>("PRODUCT_CODE").Trim(), 
    d2=>d2.Field<string>("PRODUCT_CODE").Trim(), 
    (d1,d2)=>new {d1,d2}); 
foreach(var row in results) 
{ 
    // Do stuff with row.d1/row.d2 
} 

Если, например, ваши данные таблицы создаются из источника SQL, это было бы лучше использовать соединение вместо этого, что позволит серверу SQL выполнять соединение, а не делать это на стороне клиента. Кроме того, использование не используемых данных и использование класса POCO не улучшат вашу производительность, так как вам не нужно будет вставлять/удалять код продукта во время соединения.

+0

Синтаксис Slick, но я сомневаюсь, что производительность адреса – Paparazzi

+0

Это будет быстрее, чем у него, но не так быстро, как использование hashset, как вы (я думаю). Я не верю, что LINQ будет использовать хэшеты внутри себя при выполнении соединения, но я могу ошибаться. –

+0

Конечно, это будет зависеть и от формы данных. Если dt1 имеет 1-3 записи, в то время как dt2 имеет (m | b) ионы, хешсет не сильно поможет, если он не будет отменен. –

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