我有一個包含 20 列和 25000 行的資料表。有一列稱為 URL 和一列 Language。
我需要確保所有相同的 URL 具有相同的語言。
目前我已經通過以下步驟實作了這一點
獲取所有不同(唯一)的 URL
在 URL 上創建了一個 foreach 回圈并創建了一個 DataView(在 URL 上過濾)
現在在資料視圖中,我可以檢查語言列中的所有值是否相同。
List<string> all_Distinct_Urls = helperFunction.DataTableToList(master_table, "URL"); foreach (var url in all_Distinct_Urls) { if (!string.IsNullOrEmpty(url)) { DataView dv = new DataView(master_table); dv.RowFilter = "[URL] = '" url "'"; DataTable temp_MasterTable = dv.ToTable(); List<string> all_languages = helperFunction.DataTableToList(temp_MasterTable, "Language"); if (all_languages.Count > 1) { Assert.Fail(); } } public List<string> DataTableToList(DataTable masterDataTable, string columnName, bool isDistinct = true) { List<string> list = new List<string>(); foreach (DataRow dataRow in masterDataTable.Rows) { string ID = dataRow[columnName].ToString().Trim(); list.Add(ID); } if (isDistinct) { list = list.Distinct().ToList(); } return list; }
但問題是,考慮到行數和列數,這會耗費大量時間。有沒有更快的方法來實作這一目標?
uj5u.com熱心網友回復:
我會使用 LINQ。我相信這種方法會快很多:
var invalidUrlLanguageGroups = master_table.AsEnumerable()
.GroupBy(r => r.Field<string>("Url"))
.Where(g => g.Select(r => r.Field<string>("Language")).Distinct().Skip(1).Any())
.ToList();
我按 url 分組,然后選擇所有不同的語言并檢查是否有多個。
測驗用例:
var master_table = new DataTable();
master_table.Columns.Add("Url");
master_table.Columns.Add("Language");
master_table.Rows.Add("/en-us/sample-page1", "english");
master_table.Rows.Add("/en-us/sample-page1", "german"); // fail
master_table.Rows.Add("/de-de/sample-page2", "german");
master_table.Rows.Add("/en-de/sample-page2", "english");
請注意,查詢會收集所有無效 url 及其 DataRows。如果您想要一個更有效的查詢,只確定是否至少有一個(使測驗失敗),請使用:
bool anyInvalidUrlLanguageGroups = master_table.AsEnumerable()
.GroupBy(r => r.Field<string>("Url"))
.Any(g => g.Select(r => r.Field<string>("Language")).Distinct().Skip(1).Any());
如果我想驗證所有列是否相同,而不僅僅是語言列,該怎么辦?因此,如果 URL 相同,則所有列值都應該相同
好吧,那么這種方法將有助于檢查所有列(對于每個 url 組)是否相等。您也可以在許多其他情況下使用它,因此它是一個很好的擴展候選者:
public static bool AllItemsEqual<T>(IEnumerable<IEnumerable<T>> allSequences, IEqualityComparer<T> comparer = null)
{
if (comparer == null) comparer = EqualityComparer<T>.Default;
IEnumerable<T> first = null;
foreach(IEnumerable<T> items in allSequences)
{
if (first == null)
first = items;
else
{
if (!items.SequenceEqual(first, comparer))
return false;
}
}
return true;
}
然后您將以這種方式使用它:
List<string> columnsExceptUrl = master_table.Columns.Cast<DataColumn>()
.Select(c => c.ColumnName)
.Where(n => n != "Url")
.ToList();
var urlRowsWithDifferentColumns = master_table.AsEnumerable()
.GroupBy(r => r.Field<string>("Url"))
.Where(g => !AllItemsEqual(g.Select(r => columnsExceptUrl.Select(c => r[c].ToString()))))
.ToList();
同樣,如果您只想知道它是否失敗,您可以提高效率:
bool anyUrlRowsWithDifferentColumns = master_table.AsEnumerable()
.GroupBy(r => r.Field<string>("Url"))
.Any(g => !AllItemsEqual(g.Select(r => columnsExceptUrl.Select(c => r[c].ToString()))));
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/419186.html
標籤:
