文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

.NET中求复杂类型集合的差集、交集、并集

2024-04-02 19:55

关注

前言

如标题所述,在ASP.NET应用程序开发中,两个集合做比较时 我们使用微软IEnumerable封装的Except/Intersect/Union取 差集/交集/并集 方法是非常的方便的;

但以上对于不太熟悉的小伙伴来讲,在遇到求包含引用类型(不包含string)集合时就非常的苦恼;

下面我将带着大家去了解如何通过微软自带方法方式去取**复杂类型集合**的差集、交集、并集。

场景

这里是场景,我有以下两个学生集合。

namespace Test2
{
    internal class Program
    {
        public void Main()
        {
            //列表1
            List<Student> StudentList1 = new List<Student>()
            {
                  new Student {Id=1,Name="小明",Age=27  },
                  new Student {Id=3,Name="大郭",Age=28  },
                  new Student {Id=4,Name="老登",Age=29  }
             };
            List<Student> StudentList2 = new List<Student>()
            {
                 new Student {Id=1,Name="小明",Age=27  },
                 new Student {Id=3,Name="大郭",Age=28  },
                 new Student {Id=4,Name="老登",Age=29 },
                 new Student {Id=4,Name="小路",Age=28 },
                 new Student {Id=4,Name="小明",Age=30 }
             };
        }
    }
}

生成两个实体集合;

下面我们取交集/差集/并集

完整调用示例(.NET Core):

namespace Test2
{
    internal class Program
    {
        public static void Main()
        {
            //列表1
            List<Student> StudentList1 = new List<Student>()
            {
                  new Student {Id=1,Name="小明",Age=27  },
                  new Student {Id=2,Name="大郭",Age=28  },
                  new Student {Id=3,Name="老登",Age=29  }
             };
            //列表2
            List<Student> StudentList2 = new List<Student>()
            {
                 new Student {Id=1,Name="小明",Age=27  },
                 new Student {Id=2,Name="大郭",Age=28  },
                 new Student {Id=3,Name="老登",Age=29 },
                 new Student {Id=4,Name="小路",Age=28 },
                 new Student {Id=5,Name="小明",Age=30 }
             };
            //取比列表1里多出来的学生数据 并输出
            var ExceptData = StudentList2.Except(StudentList1);
            Console.WriteLine("差集:" + String.Join(";", ExceptData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; })));
            //取列表1与列表2里共有的学生数据
            var IntersectData = StudentList1.Intersect(StudentList2);
            Console.WriteLine("交集:" + String.Join(";", IntersectData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; })));
            //获取办理所有学生的数据(一个相同的学生只能一条)
            var UnionData = StudentList1.Union(StudentList2);
            Console.WriteLine("并集:"+String.Join(";", UnionData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; })));
        }
    }
}

输出:

  差集:1-小明-27;2-大郭-28;3-老登-29;4-小路-28;5-小明-30
  交集:null
  并集:1-小明-27;2-大郭-28;3-老登-29;1-小明-27;2-大郭-28;3-老登-29;4-小路-28;5-小明-30

以上输出仔细看一下明显是不对的,这就涉及到了复杂类型对比,请看代码:

正常我们声明的类

/// <summary>
/// 学生类
/// </summary>
internal class Student
{
    /// <summary>
    /// 编号
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 姓名
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 年龄
    /// </summary>
    public int Age { get; set; }

}

因为我们要对比的是引用类型,因为在对比除string引用类型外,其他引用类型的对比默认都是对比的堆里地址,所以我们要实现一个自定义的对比方案

我们需要继承一个接口IEqualityComparer<T> 泛型接口

如下:(这里我们以年龄与名做为对比条件)

/// <summary>
/// 学生类
/// </summary>
internal class Student : IEqualityComparer<Student>
{
    /// <summary>
    /// 编号
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 姓名
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 年龄
    /// </summary>
    public int Age { get; set; }

    /// <summary>
    /// 比较器
    /// </summary>
    /// <param name="s1">比较实体1</param>
    /// <param name="s2">比较实体2</param>
    /// <returns></returns>
    public bool Equals(Student s1, Student s2)
    {
        //验证相等条件
        if (s1.Name == s2.Name && s1.Age == s2.Age)
        {
            return true;
        }
        return false;
    }

    /// <summary>
    /// 获取唯一条件
    /// </summary>
    /// <param name="stu"></param>
    /// <returns></returns>
    public int GetHashCode(Student stu)
    {
        return (stu.Name + "|" + stu.Age).GetHashCode();
    }
}

修改了类后还有最重要的一点:就是修改比较的方法(相当于声明一个自定义的比较器给方法)

//取比列表1里多出来的学生数据 并输出
            var ExceptData = StudentList2.Except(StudentList1,new Student());
            Console.WriteLine("差集:" + String.Join(";", ExceptData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; })));

            //取列表1与列表2里共有的学生数据
            var IntersectData = StudentList1.Intersect(StudentList2,new Student());
            Console.WriteLine("交集:" + String.Join(";", IntersectData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; })));

            //获取办理所有学生的数据(一个相同的学生只能一条)
            var UnionData = StudentList1.Union(StudentList2,new Student());
            Console.WriteLine("并集:"+String.Join(";", UnionData.Select(x => { return $"{x.Id}-{x.Name}-{x.Age}"; })));

输出:

  差集:4-小路-28;5-小明-30 

  交集:1-小明-27;2-大郭-28;3-老登-29

  并集:1-小明-27;2-大郭-28;3-老登-29;4-小路-28;5-小明-30

到这里引用类型的比较已经完成了,比较器的条件方法可以根据需求调整,如有不足之处,希望大家多多指正!!!

到此这篇关于.NET的求复杂类型集合的差集、交集、并集的文章就介绍到这了,更多相关.net差集、交集、并集内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯