扩展lamda表达中distinct按照字段去除重复

时间:2021-06-06 00:39:33

 首先,我们定义一个Student类来测试.

  

 public class Student    {        public int ID { get; set; }        public string Name { get; set; }        public int Age { get; set; }    } 

      

 List<Student> data = new List<Student> {                 new Student(){ID=1,Name="名字1",Age=15},                 new Student(){ID=1,Name="名字2",Age=15},                  new Student(){ID=3,Name="名字3",Age=17},                   new Student(){ID=4,Name="名字4",Age=18},                    new Student(){ID=5,Name="名字5",Age=19},                     new Student(){ID=6,Name="名字6",Age=20}            };

    在这样一个数据中. 我们发现,如果使用自带的 Distinct ,发现得数据依然是一样,并没有想象中的去除重复。

    以下,给出几个解决方案。

   第一种: 继承EqualityComparer

    我们新建一个类。如下。且必须重写父类中的抽象方法。Equals和GetHashCode

  

public class StudentComparer : EqualityComparer<Student>    {        public override bool Equals(Student s1, Student s2)        {            //这里写你要去除重复的条件。            return s1.ID == s2.ID && s1.Name == s2.Name;        }        public override int GetHashCode(Student student)        {            return student.ID.GetHashCode();        }    }

    使用方法:data.Distinct(new StudentComparer()); 

    可以达到我们预料的效果,当然,这样比较麻烦一点。

  第二种。我们可以根据非关联泛型集合HashSet<T>中的唯一性对distinct扩展

    如何写扩展方法,这里我就不再细说。

    具体扩展如下。

    

namespace  System.Linq{    public static class Class1    {       public static IEnumerable<T> DistinctBy2<T, TResult>(this IEnumerable<T> source, Func<T, TResult>  where)        {            HashSet<TResult> hashSetData= new HashSet<TResult>();            foreach (T item in source)            {                if (hashSetData.Add(where(item)))                {                    yield return item;                }            }        }      }}

    使用方法如下:data.DistinctBy2(p => new { p.ID,p.Name}).ToList<Student>();  //其中new {p.ID,P.Name}这里可指定要根据去重的字段

    第三种。直接简单一点。通过先分组,然后在每个组里面取第一项。

   代码如下:

  

//Lamda:    new {item.ID,item.Name}指定去重字段data.GroupBy(item => new { item.ID,item.Name }).Select(item =>  item.First()).ToList<Student>();//-----------------------------------------------------------------//Linq      new {item.ID,item.Name}指定去重字段                        (from item in data                         group item by new { item.ID,item.Name} into g                          select g.First()).ToList<Student>();                                

 

      以上三种,都可以达到去重效果。当然,你可以选择第二种的扩展方法。

      具体使用,看个人喜欢。

      本文到此结束。