List根据某个字段(属性)去重
更新:2021-06-01
结合大佬@秋荷雨翔给出的方法(原文链接地址:https://www.cnblogs.com/s0611163/archive/2019/08/23/11399898.html),做了个简单的实验(根据用户姓名去重),实验不严谨,仅供参考
1 void Main() 2 { 3 //生成测试数据 4 DateTime dt = DateTime.Now; 5 Random rnd = new Random(); 6 List<User> list = new List<User>(); 7 int total = 1000; 8 for (int i = 0; i < total; i++) 9 { 10 User user = new User(); 11 user.Id = rnd.Next(1, total * 10); 12 user.Name = rnd.Next(1, total * 10).ToString(); 13 user.Old = rnd.Next(1,100); 14 list.Add(user); 15 } 16 double d = DateTime.Now.Subtract(dt).TotalMilliseconds; 17 18 //方法一 19 DateTime dt1 = DateTime.Now; 20 Dictionary<string, User> result1 = new Dictionary<string, User>(); 21 foreach (User item in list) 22 { 23 User temp; 24 if (!result1.TryGetValue(item.Name, out temp)) 25 { 26 result1.Add(item.Name, item); 27 } 28 } 29 List<User> r1 = result1.Values.ToList(); 30 double d1 = DateTime.Now.Subtract(dt1).TotalMilliseconds; 31 32 //方法二 33 DateTime dt2 = DateTime.Now; 34 List<User> result2 = list.ToLookup(item => item.Name).ToDictionary(item => item.Key, item => item.First()).Values.ToList(); 35 double d2 = DateTime.Now.Subtract(dt2).TotalMilliseconds; 36 37 //方法三 38 DateTime dt3 = DateTime.Now; 39 List<User> result3 = list.Where((x,i)=>list.FindIndex(z=>z.Name == x.Name) == i).ToList(); 40 double d3 = DateTime.Now.Subtract(dt3).TotalMilliseconds; 41 42 Console.WriteLine("生成 " + list.Count.ToString("# ####") + " 条测试数据耗时:" + d + "毫秒"); 43 Console.WriteLine("使用方法一去重耗时:" + d1 + "毫秒"); 44 Console.WriteLine("使用方法二去重耗时:" + d2 + "毫秒"); 45 Console.WriteLine("使用方法三去重耗时:" + d3 + "毫秒"); 46 Console.WriteLine("去重后数量:" + r1.Count + "," + result2.Count + "," + result3.Count); 47 } 48 49 50 public class User 51 { 52 public int Id {get;set;} 53 public string Name {get;set;} 54 public int Old {get;set;} 55 }
一千条数据结果:
一万条数据结果:
十万条数据结果:
百万条数据结果:运行时间太长,5分钟以上了,不等了,取消了
总结:
1、数据量越大三种方法耗时差距越明显
2、方法一、二各有优缺点,看具体场景
3、方法三不推荐(piapia打脸)
----我是分割线 以下是原文----
有时候自带的list.Distinct()去重并不能满足魔门的要求,比如以下情况
如果testList的Name相同则视为重复,则可以如下实现,比写循环语句简洁多了
testList.Where((x,i)=>testList.FindIndex(z=>z.name == x.name) == i)
PS:
参数x对应最外层的testList
参数i对应最外层testList内元素的位置索引(第几个元素)
参数z对应内层的testList