C#中foreach遍历DataTable时如何提前比对下一行实现条件去重统计
原有代码问题说明
- 州匹配逻辑如果是要精确统计加州(CA)的交易,用
Contains会出现误匹配,建议直接用等值判断 - 你写的
row["InvNum"]+1.ToString()是将当前行的发票号字符串末尾拼接字符1,完全没有实现取下一行发票号对比的逻辑 - 对比相邻行的去重逻辑仅适用于重复发票号的行相邻排列的场景,如果你的DataTable里重复行不相邻会统计错误,更稳妥的方案是用集合存储已统计过的发票号
实现方案
方案1:按索引循环(符合你原有对比下一行的逻辑)
假设你的DataTable变量名为dt,实现代码如下:
int californiaTransactions2021 = 0; // 用for循环按索引遍历才能取到下一行 for (int i = 0; i < dt.Rows.Count; i++) { DataRow row = dt.Rows[i]; // 先判断是不是加州的记录 if (row["State"].ToString().Trim() == "CA") { californiaTransactions2021++; // 不是最后一行的话,对比下一行的发票号 if (i < dt.Rows.Count - 1) { DataRow nextRow = dt.Rows[i + 1]; if (row["InvNum"].ToString().Trim() == nextRow["InvNum"].ToString().Trim()) { californiaTransactions2021--; } } } }
方案2:HashSet去重(更稳妥,不要求重复行相邻)
不管重复的发票号行是不是挨在一起都能正确去重,推荐用这个方案:
int californiaTransactions2021 = 0; HashSet<string> countedInvs = new HashSet<string>(); foreach (DataRow row in dt.Rows) { string state = row["State"].ToString().Trim(); string invNum = row["InvNum"].ToString().Trim(); if (state == "CA" && !countedInvs.Contains(invNum)) { californiaTransactions2021++; countedInvs.Add(invNum); } }
方案3:LINQ简洁写法
如果你熟悉LINQ的话可以用更短的代码实现:
var californiaTransactions2021 = dt.AsEnumerable() .Where(r => r["State"].ToString().Trim() == "CA") .Select(r => r["InvNum"].ToString().Trim()) .Distinct() .Count();
内容的提问来源于stack exchange,提问作者hidden82
相关产品推荐
相关产品推荐

