勇哥谈下去除List的重复元素的问题

勇哥注:

去除List的重复元素的问题是比较常见的需求,C#有标准的做法,以后不要自己写了。


    public class Student
    {
        public string Name { get; private set; }
        public int Id { get; private set; }
        public string Hobby { get; private set; }
        public Student(string name, int id, string hobby)
        {
            this.Name = name;
            this.Id = id;
            this.Hobby = hobby;
        }
        /// <summary>
        /// 方便输出,重写ToString方法
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("{0}\t{1}\t{2}", this.Name, this.Id, this.Hobby);
        }
    }

    public class Compare : IEqualityComparer<Student>
    {
        public bool Equals(Student x, Student y)
        {
            return x.Id == y.Id;//可以自定义去重规则,此处将Id相同的就作为重复记录,不管学生的爱好是什么
        }
        public int GetHashCode(Student obj)
        {
            return obj.Id.GetHashCode();
        }
    }

调用者:

List<Student> list = new List<Student>() {
    new Student("James",1,"Basketball"),
    new Student("James",1,"Basketball"),
    new Student("Kobe",2,"Basketball"),
    new Student("Curry",3,"Football"),
    new Student("Curry",3,"Yoga"),
    new Student("Curry",3,"Yoga2")
};
var res = list.Distinct(new Compare()).ToList();
res.ForEach(s => richTextBox2.AppendText($"{s.Name},{s.Id},{s.Hobby}\n"));

结果:

id=1,id=3的项目却重复成功都只保留了一个。

image.png


说明:

(1)Enumerable.Distinct 方法 是常用的LINQ扩展方法,属于System.Linq的Enumerable方法,可用于去除数组、集合中的重复元素,还可以自定义去重的规则。

(2)对于数值类形的集合,可以直接用无参数Distinct

(3)对于引用类形数据的集合,需要带参Distinct

上面的例演示了带参数Distinct的用法。

不带comparer参数的Distinct方法是使用的IEqualityComparer接口的默认比较器进行比较的,对于引用类型,
默认比较器比较的是其引用地址,程序中集合里的每一个元素都是个新的实例,
引用地址都是不同的,所以不会被作为重复记录删除掉。

(4)去重复规则只需要新建一个类去实现IEqualityComparer接口。

        这个接口说明如下:

        1、 注意GetHashCode方法的实现,只有HashCode相同才会去比较

        2、 当检测到HashCode值相同的项目时,会触发一次Equals函数,按其中定义的规则进行却除重复。

    public class Compare : IEqualityComparer<Student>
    {
        public bool Equals(Student x, Student y)
        {
            return x.Id == y.Id;
        }
        public int GetHashCode(Student obj)
        {
            return obj.Id.GetHashCode();
        }
    }

        3、对于上面例子中的HashCode来说,就是字段Id,如下所示:

            其中id=1的项目有两个,会调用Equals函数去重复一次,

            id=3的三个项目会调用Equals函数去重复二次。

List<Student> list = new List<Student>() {
    new Student("James",1,"Basketball"),
    new Student("James",1,"Basketball"),
    new Student("Kobe",2,"Basketball"),
    new Student("Curry",3,"Football"),
    new Student("Curry",3,"Yoga"),
    new Student("Curry",3,"Yoga2")
};

        所以上面例子如果每项的id都不同的话,去重复将没有效果。

        显然,很多时候,如果不是分组去重复的话,你应该把这个id置为同一个值,这样才能达到去重复的效果。

        另外,你的数据结构如果没有id字段,那么请加上这个字段。



--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2023-03-13 16:10:06 编辑
  • 评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年5月    »
12345
6789101112
13141516171819
20212223242526
2728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864