如何在List中查找特定元素并实现基于属性的去重添加
在List中查找特定元素与过滤去重实现方案
一、如何在List中查找特定元素?
在C#的List<T>里,有几种实用的查找方法,你可以根据需求选:
Find()方法:返回列表中第一个匹配条件的元素,找不到就返回default(T)(引用类型就是null)// 找第一个item属性等于目标值的元素 cPolyline foundItem = PolyLineList.Find(x => x.item == targetItem);Exists()方法:直接判断列表里有没有符合条件的元素,返回布尔值bool hasMatch = PolyLineList.Exists(x => x.item == targetItem);LINQ的
FirstOrDefault()(需要先引入System.Linq命名空间):和Find()逻辑类似,返回第一个匹配元素,找不到返回默认值cPolyline foundItem = PolyLineList.FirstOrDefault(x => x.item == targetItem);LINQ的
Any():和Exists()作用一致,用LINQ风格判断是否存在匹配元素bool hasMatch = PolyLineList.Any(x => x.item == targetItem);
二、解决你的List过滤去重问题
先拆解你的需求:要避免往PolyLineList里加item属性重复的cPolyline实例,也就是列表里已有相同item的元素时,就跳过添加。你的现有代码有两个小问题:
- 逻辑冗余:
PolyLineList.Find(...)找到的元素肯定在列表里,找不到就返回null,再用Contains()判断完全没必要; - 效率偏低:
Find()已经遍历了一次列表,Contains()可能还要再遍历一次,等于做了两次重复工作。
改进后的代码方案
方案1:用List<T>.Exists()(推荐,不用额外引入LINQ)
if (!PolyLineList.Exists(x => x.item == item)) { cPolyline currentPolyLine = new cPolyline(pointlist, item); PolyLineList.Add(currentPolyLine); }
Exists()会遍历列表,找到第一个符合条件的元素就停下,只需要一次遍历就能完成判断,逻辑直接又高效。
方案2:用LINQ的Any()(适合已经在用LINQ的项目)
先在文件顶部加命名空间:
using System.Linq;
然后修改代码:
if (!PolyLineList.Any(x => x.item == item)) { cPolyline currentPolyLine = new cPolyline(pointlist, item); PolyLineList.Add(currentPolyLine); }
Any()和Exists()逻辑一样,只是写法更简洁,是LINQ场景下的常用判断方式。
方案3:用HashSet<T>实现高效去重(适合大数据量频繁添加的场景)
如果你的列表数据量很大,还经常要做添加去重操作,List<T>的O(n)判断效率会跟不上,推荐用HashSet<T>加自定义比较器,它的Contains()和Add()都是O(1)的时间复杂度:
先写一个比较器,用来判断两个cPolyline是否因为item重复而视为相同:
public class cPolylineItemComparer : IEqualityComparer<cPolyline> { public bool Equals(cPolyline x, cPolyline y) { if (x == null || y == null) return x == y; // 这里根据你的item类型调整比较逻辑,值类型直接比,引用类型可能要更细致的判断 return x.item.Equals(y.item); } public int GetHashCode(cPolyline obj) { // 基于item的哈希值生成,保证相同item的实例哈希值一致 return obj.item.GetHashCode(); } }
然后初始化HashSet并添加元素:
// 初始化时传入自定义比较器 HashSet<cPolyline> polyLineSet = new HashSet<cPolyline>(new cPolylineItemComparer()); // 添加时HashSet会自动判断是否重复,返回布尔值表示是否添加成功 cPolyline currentPolyLine = new cPolyline(pointlist, item); polyLineSet.Add(currentPolyLine);
这种方式在大数据量场景下性能优势特别明显。
内容的提问来源于stack exchange,提问作者Lion Hunter
相关产品推荐
相关产品推荐

