在C#中按值判断数组相等(尽量避免使用LINQ)
问题分析与解决方案
核心问题:当前循环逻辑错误导致重复添加
你现在的代码逻辑存在根本性问题:对于每个待添加的坐标,只要burnzones里有任意一个坐标和它不相等,就会把它加入newburns。这会导致同一个坐标被重复添加多次(比如burnzones有5个元素,其中4个和它不等,就会被加4次),完全违背了“只添加不在burnzones中的坐标”的需求。
第一步:修复循环逻辑
先把判断逻辑改对——先假设坐标不在burnzones里,遍历完所有元素后确认确实没匹配到,再添加:
foreach (KeyValuePair<int[], char> entry in returns) { if (entry.Value == 'x') { bool existsInBurnZones = false; foreach (int[] burn in burnzones) { if (Equals(burn, entry.Key)) { existsInBurnZones = true; break; // 找到匹配项就终止遍历,提升效率 } } if (!existsInBurnZones) { newburns.Add(entry.Key); } } }
第二步:优化相等判断方法
你之前用字符串拼接的方式效率很低,直接对比数组元素更快(尤其是固定长度的二元坐标):
public bool Equals(int[] x, int[] y) { // 先判空,再确保是二元坐标,最后对比两个元素 return x != null && y != null && x.Length == 2 && y.Length == 2 && x[0] == y[0] && x[1] == y[1]; }
第三步:用更高效的结构解决频繁查找问题
因为你的场景需要频繁增删和去重,List<int[]>的O(n)查找效率会越来越低,推荐用HashSet来优化,它的查找是O(1)级别。
方案1:改用Tuple<int, int>代替int[](最简单)
Tuple<int, int>是值类型,默认会按元素判断相等,无需自定义比较器:
// 替换原有类型:List<int[]> → List<Tuple<int, int>>,Dictionary<int[], char> → Dictionary<Tuple<int, int>, char> HashSet<Tuple<int, int>> burnZoneSet = new HashSet<Tuple<int, int>>(burnzones); foreach (var entry in returns) { if (entry.Value == 'x') { if (!burnZoneSet.Contains(entry.Key)) { newburns.Add(entry.Key); burnZoneSet.Add(entry.Key); // 后续去重可以直接用这个集合 } } }
方案2:保留int[],自定义HashSet比较器
如果不想修改现有数据类型,可以给HashSet传入自定义的相等比较器:
public class CoordinateComparer : IEqualityComparer<int[]> { public bool Equals(int[] x, int[] y) { return x != null && y != null && x.Length == 2 && y.Length == 2 && x[0] == y[0] && x[1] == y[1]; } public int GetHashCode(int[] obj) { // 生成基于坐标元素的哈希码,确保HashSet能正确分组 if (obj == null || obj.Length != 2) return 0; return HashCode.Combine(obj[0], obj[1]); } } // 使用方式 HashSet<int[]> burnZoneSet = new HashSet<int[]>(burnzones, new CoordinateComparer()); foreach (var entry in returns) { if (entry.Value == 'x') { if (!burnZoneSet.Contains(entry.Key)) { newburns.Add(entry.Key); burnZoneSet.Add(entry.Key); } } }
内容的提问来源于stack exchange,提问作者nos codemos
相关产品推荐
相关产品推荐

