如何在C#中实现列表元素与其他所有元素的比较(排除自身)
几种实现思路
1. 直接用索引遍历(最直观高效)
放弃foreach,改用for循环直接操作索引,能轻松跳过自身元素,性能表现也更好:
List<sometype> A = new List<sometype>(); for (int i = 0; i < A.Count; i++) { var e1 = A[i]; for (int j = 0; j < A.Count; j++) { if (i == j) continue; // 跳过自身元素 var e2 = A[j]; // 执行e1和e2的比较逻辑 } }
2. 带索引的foreach遍历
如果偏好foreach语法,可以用Enumerable.Select的索引重载,拿到元素对应的索引后过滤掉自身:
List<sometype> A = new List<sometype>(); foreach (var (e1, index1) in A.Select((item, idx) => (item, idx))) { foreach (var (e2, index2) in A.Select((item, idx) => (item, idx))) { if (index1 == index2) continue; // 执行e1和e2的比较逻辑 } }
如果是C# 7.0之前的版本(不支持元组语法),可以改用匿名对象:
foreach (var item1 in A.Select((item, idx) => new { Item = item, Index = idx })) { foreach (var item2 in A.Select((item, idx) => new { Item = item, Index = idx })) { if (item1.Index == item2.Index) continue; // 执行item1.Item和item2.Item的比较逻辑 } }
3. 基于Skip/Take的过滤(不推荐,性能不如索引直接判断)
如果一定要用Skip,可以先获取当前元素的索引,再将列表拆分为索引前后的两部分拼接(排除自身):
List<sometype> A = new List<sometype>(); foreach (var (e1, index1) in A.Select((item, idx) => (item, idx))) { // 拼接索引之前和之后的元素,排除自身 var otherElements = A.Take(index1).Concat(A.Skip(index1 + 1)); foreach (var e2 in otherElements) { // 执行e1和e2的比较逻辑 } }
这种方式会额外创建枚举器,性能比直接用索引判断差一些,除非有特殊场景,否则不推荐。
内容的提问来源于stack exchange,提问作者BoyOfJoy
相关产品推荐
相关产品推荐

