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

 更新时间:2022年07月28日 14:31:17   作者:清风不在已徐来  
这篇文章主要介绍了.NET的求复杂类型集合的差集、交集、并集,下面我将带着大家去了解如何通过微软自带方法方式去取**复杂类型集合**的差集、交集、并集,需要的朋友可以参考下

前言

如标题所述,在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差集、交集、并集内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • AspNetPager与Socut.Data使用实例代码

    AspNetPager与Socut.Data使用实例代码

    最近对AspNetPager与Socut.Data这两个控件产生了浓厚的兴趣,这两个控件配合可以减轻很多程序员编写代码的压力。ASpNetPager为分页控件,而Socut.Data为数据操作控件,ACCESS,MSSQL都可以。
    2008-07-07
  • ASP.NET使用TreeView显示文件的方法

    ASP.NET使用TreeView显示文件的方法

    这篇文章主要介绍了ASP.NET使用TreeView显示文件的方法,包括控件的使用、页面加载代码及节点事件,是WEB应用程序中非常实用的技巧,需要的朋友可以参考下
    2014-09-09
  • asp.net core webapi 服务端配置跨域的实例

    asp.net core webapi 服务端配置跨域的实例

    下面小编就为大家分享一篇asp.net core webapi 服务端配置跨域的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • 详解.net core webapi 前后端开发分离后的配置和部署

    详解.net core webapi 前后端开发分离后的配置和部署

    这篇文章主要介绍了.net core webapi 前后端开发分离后的配置和部署,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • .Net Core 2.2升级3.1的避坑指南(小结)

    .Net Core 2.2升级3.1的避坑指南(小结)

    这篇文章主要介绍了.Net Core 2.2升级3.1的避坑指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • asp.net实现的计算网页下载速度的代码

    asp.net实现的计算网页下载速度的代码

    刚看到有人给出asp.net实现的计算网页下载速度的方法,本方法未经本人测试,不知道能否可靠性如何。准确来说,这只是个思路吧
    2013-03-03
  • ASP.NET内置对象之Application对象

    ASP.NET内置对象之Application对象

    Application对象是HttpApplicationState类的一个实例,它可以产生一个所有Web应用程序都可以存取的变量,这个变量的可以存取范围涵盖全部使用者,也就是说只要正在使用这个网页的程序都可以存取这个变量。
    2008-09-09
  • 详解.Net单元测试方法

    详解.Net单元测试方法

    本篇文章给大家详细讲述了.NET单元测试的详细方法和步骤,有需要的朋友参考学习下。
    2018-07-07
  • 使用Entity Framework(4.3.1版本)遇到的问题整理

    使用Entity Framework(4.3.1版本)遇到的问题整理

    在这里记录一下之前使用Entity Framework(4.3.1版本)遇到的问题:更新没有设置主键的表、更改Code-First的默认连接、检测字符串截断错误,需要的朋友可以参考下
    2012-12-12
  • Visual Studio 2017正式版发布 亮点看这里

    Visual Studio 2017正式版发布 亮点看这里

    终于等到你,最强 IDE Visual Studio 2017 正式版发布,这篇文章主要为大家详细解析了Visual Studio 2017正式版发布的细节,亮点看这里
    2017-03-03

最新评论