Сравнение двух наборов может иметь сложность O (n2). Это плохо. Вы можете улучшить это, если у вас есть начальный поиск хеша.
var Set1 = new Dictionary<string, int>();
//Prehash all values in the set that won't be deleted from
for (int i = 0; i < CollectionIn.Rows.Count; i++)
{
string value1 = CollectionIn.Rows[i].ItemArray[0].ToString().ToLower();
Set1.Add(value1, i);
}
//Loop over the other set
for (int i2 = 0; i2 < CollectionIn2.Rows.Count; i2++)
{
string value2 = CollectionIn2.Rows[i2].ItemArray[0].ToString().ToLower();
int foundIndex;
if (Set1.TryGetValue(value2, out foundIndex) == false)
continue;
//Remove value1 when value1 == value2
CollectionIn.Rows[foundIndex].Delete();
}
CollectionIn.AcceptChanges(); //It's probably best to save changes last as a single call
I хэшируется CollectionIn, а затем повторяется CollectionIn2. Это означает, что мне нужен словарь, поэтому для удаления мне нужен индекс CollectionIn. Если бы это было наоборот, и CollectionIn2 был хеширован, то это был бы только хэш-набор, и было бы лучше, потому что он мог бы обрабатывать внутренние дубликаты в наборе CollectionIn, поэтому:
var Set2 = new HashSet<string>();
//Prehash all values in one set (ideally the larger set)
for (int i2 = 0; i2 < CollectionIn2.Rows.Count; i2++)
{
string value2 = CollectionIn2.Rows[i2].ItemArray[0].ToString().ToLower();
if (Set2.Contains(value2))
continue; //Duplicate value
else
Set2.Add(value2);
}
//Loop over the other set
for (int i1 = 0; i1 < CollectionIn.Rows.Count; i1++)
{
string value1 = CollectionIn.Rows[i1].ItemArray[0].ToString().ToLower();
if (Set2.Contains(value1) == false)
continue;
//Remove value1 when value1 == value2
CollectionIn.Rows[i1].Delete();
}
CollectionIn.AcceptChanges(); //It's probably best to save changes last as a single call
Этот шаблон будет применяться ко многим типам наборов данных (включая Список, массив и т. Д.). Конечно, если вы можете написать SQL для удаленных наборов данных в той же базе данных, это лучше.
Если вы любите лямбда-функции, это должно выглядеть примерно так:
var alreadyInSet2 = new HashSet<string>(CollectionIn2.Rows.Cast<DataRow>()
.Select(x => x[0].ToString().ToLower()));
CollectionIn.Rows.Cast<DataRow>()
.Where(y => alreadyInSet2.Contains(y[0].ToString().ToLower()) == false)
.ToList() //I think you technically need this before calling ForEach
.ForEach(y => y.Delete());
CollectionIn.AcceptChanges();
См. Также: С двумя очень большими списками / коллекциями - как эффективно обнаруживать и / или удалять дубликаты - где больше времени / работы может уйти в более широкий порядок ответов и повышения производительности.