C# DataTable逗号分隔页码重复校验误判问题修复
问题根因
你的判断完全正确,误报的核心原因是string.Contains()是子串匹配逻辑:校验页码1时,字符串"10"因为包含字符子串"1"就会被判定为匹配,本质是没有把每个单元格内逗号分隔的页码拆成独立值做等值比对,才会出现跨数字位的误判。
除此之外原代码还有三个逻辑缺陷:
- 三层嵌套循环每次都全表遍历计数,数据量稍大时效率很低
- 计数判断触发时机不对,遍历过程中就判断count>1,既可能提前触发误判,也无法识别同一行内用户手滑输入的重复值(比如
"1,1,2") - 没有做基础输入容错,用户输入时不小心带的空格、多余逗号都会导致校验失效
修复方案
核心思路很简单:把所有行的page_numb按逗号拆成独立的单个页码,做基础的去空格处理后,再检查是否有重复值即可,不需要写复杂的嵌套计数逻辑。
易理解的基础实现(适合初学者)
用HashSet做查重容器,它的Add方法会直接返回布尔值:如果值已存在就返回false,不存在就添加成功返回true,比手动循环计数效率高很多。
HashSet<string> existedPages = new HashSet<string>(); for (int i = 0; i < dttemp.Rows.Count; i++) { // 拆分当前行的页码,自动忽略多余逗号产生的空值 string[] pageItems = dttemp.Rows[i]["page_numb"].ToString() .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int p = 0; p < pageItems.Length; p++) { // 去掉页码前后误输入的空格 string currentPage = pageItems[p].Trim(); // 添加失败说明页码已经存在,触发重复提示 if (!existedPages.Add(currentPage)) { MessageBox.Show($"页码{currentPage}被重复输入,请检查后重试"); return; } } } // 所有页码遍历完成无重复,校验通过
这个实现完全避免了子串匹配的问题:"1"和"10"是拆分后的两个独立字符串,等值比对时不会被判定为相同,从根源解决误报。同时自带基础输入容错,能处理用户多打空格、多打逗号的常见输入错误。
简洁LINQ实现
如果项目允许使用LINQ,可以用更短的代码实现同样的效果:
// 拉取所有拆分、去空格后的页码 List<string> allPages = dttemp.AsEnumerable() .SelectMany(row => row.Field<string>("page_numb") .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(pageStr => pageStr.Trim())) .ToList(); // 查找第一个重复项 var duplicate = allPages.GroupBy(p => p).FirstOrDefault(g => g.Count() > 1); if (duplicate != null) { MessageBox.Show($"页码{duplicate.Key}被重复输入,请检查后重试"); return; }
扩展提示
如果后续需要支持页码范围输入(比如1-10这种格式),只需要在拆分页码的步骤增加范围解析逻辑即可,当前的查重核心逻辑不需要改动。
内容的提问来源于stack exchange,提问作者sedativo22
相关产品推荐
相关产品推荐

