Я пытаюсь создать метод, который при задании таблицы удалит похожие строки. То, что я думал сделать, это создать двойной цикл foreach
, так что каждая отдельная строка в таблице будет сравниваться со всеми остальными.Метод, который сравнивает и удаляет все аналогичные строки в datatable
private void comparaeapagarowsiguais(DataTable table1)
{
foreach (DataRow row1 in table1.Rows)
{
foreach (DataRow row2 in table1.Rows)
{
var array1 = row1.ItemArray;
var array2 = row2.ItemArray;
if (array1.SequenceEqual(array2))
{
table1.Rows.Remove(row2);
}
}
}
}
Проблема заключается в том, что в какой-то момент, любая данная строка будет сравнивать с собой, и, таким образом, будет пытаться удалить себя (и я бы оканчиваться не рядами на всех). Но я хочу сохранить хотя бы одну из разных строк.
Как я могу проехать через них, избегая при этом любой строки, которую можно сравнить с собой?
EDIT: Частичное решение
Я придумал решение, которое работает в моем случае. Это будет работать, если аналогичные строки будут немедленно расположены рядом друг с другом. (Если подобные строки разбросаны по всему столу он не будет работать)
private void comparalinhaseapaga(DataTable table1)
{ //I will explain the try in the end
try
{
//you will run i for as long as you like
for (int i = 0; ;)
{
//you create 2 arrays from i, and i+1, this means you will compare
//the first 2 lines of the data table
var array1 = table1.Rows[i].ItemArray;
var array2 = table1.Rows[i + 1].ItemArray;
//if they are similar, it removes row at 1, and will go back to the cycle and
//proceed to compare row at 0 with the previously row at 2
if (array1.SequenceEqual(array2))
{
table1.Rows.RemoveAt(i + 1);
}
else
{
//if they are not equal, it move next to row at 1, and compare it with row at 2
//once it gets here, the row 0 and row 1 are already different
//that's why it only works when the similar rows are adjacent to another
i++;
}
}
}
catch { }
}
Попробовать и поймать это потому, что в какой-то момент он не будет иметь строку в позиции я + 1 для сравнения, и будет производить ошибка. Использование try/catch пропустит ошибку и продолжит, что вы можете сделать, поскольку все аналогичные строки уже удалены. Протестировано и обработано;)
Надеюсь, это полезно для кого-то.
Edit 2: Найдена чистое решение, просто взять этот код:
private DataTable RemoveDuplicatesRecords(DataTable dt)
{
//Returns just unique rows
var UniqueRows = dt.AsEnumerable().Distinct(DataRowComparer.Default);
DataTable dt2 = UniqueRows.CopyToDataTable();
return dt2;
}
Какая цель? вы пытаетесь достичь массива типа данных? – McShep
Это для удобства чтения конечному пользователю, ему не нужны 2 одинаковых строки, одного достаточно. – ng80092b