首页 > 编程语言 >C# 集合交、并、差、去重,对象集合交并差

C# 集合交、并、差、去重,对象集合交并差

时间:2024-11-15 14:09:02浏览次数:1  
标签:Product return C# product 交并 集合 new null public

转自:https://www.cnblogs.com/hao-1234-1234/p/10408602.html

关键词:C#  List 集合 交集、并集、差集、去重, 对象集合、 对象、引用类型、交并差、List<T>

有时候看官网文档是最高效的学习方式!

 

一、简单集合

Intersect 交集,Except 差集,Union 并集
int[] oldArray = { 1, 2, 3, 4, 5 };
int[] newArray = { 2, 4, 5, 7, 8, 9 };
var jiaoJi = oldArray.Intersect(newArray).ToList();//2,4,5
var oldChaJi = oldArray.Except(newArray).ToList();//1,3
var newChaJi = newArray.Except(oldArray).ToList();//7,8,9
var bingJi = oldArray.Union(newArray).ToList();//1,2,3,4,5,7,8,9

二、对象集合

Product[] store1 = { 
     new Product { Name = "apple", Code = 9 }, 
     new Product { Name = "orange", Code = 4 } 
};

Product[] store2 = {
     new Product { Name = "apple", Code = 9 }, 
     new Product { Name = "lemon", Code = 12 }
 };

IEnumerable<Product> union =store1.Union(store2,new ProductComparer());
IEnumerable<Product> except=store1.Except(store2,new ProductComparer());
IEnumerable<Product> intersect=store1.Intersect(store2,new ProductComparer());
IEnumerable<Product> distinct=store1.Distinct(store2,new ProductComparer());

小提示:

1:IEnumerable<Product> 可以简化为 匿名类型 var
对自己去重:
var distinct=store1.Distinct(new ProductComparer());
相对于别人去重
var distinct=store1.Distinct(store2,new ProductComparer());
2: 可以继续进行一些linq或拉姆达操作
 var distinct=store1.Distinct(store2,new ProductComparer()).OrderBy(c=>c.Code);
原因是引用了linq组件:using System.Linq;

三、比较类的实现
public class Product
{  public string Id {get;set}
    public string Name { get; set; }
    public int Code { get; set; }
}

1只有一个比较条件

//如果对象存在唯一主键,例如:从数据库里查询出来的数据存在 ID

class ProductComparer : IEqualityComparer<Product>
{
    // Products are equal if their names and product numbers are equal.
    public bool Equals(Product x, Product y)
    {
       
        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the products' properties are equal.
        return x.ID == y.ID;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(Product product)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(product, null)) return 0;


        //Get hash code for the Code field.
        int hashID = product.ID.GetHashCode();

        //Calculate the hash code for the product.
        return hashID;
    }

}

2 多个比较条件

// 如果存在组合主键或组合唯一索引,即多个字段组合才能确定唯一性。
// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<Product>
{
    // Products are equal if their names and product numbers are equal.
    public bool Equals(Product x, Product y)
    {
       
        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the products' properties are equal.
        return x.Code == y.Code && x.Name == y.Name;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(Product product)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(product, null)) return 0;

        //Get hash code for the Name field if it is not null.
        int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();

        //Get hash code for the Code field.
        int hashProductCode = product.Code.GetHashCode();

        //Calculate the hash code for the product.
        return hashProductName ^ hashProductCode;
    }

}

3 难道我们每次都要“简单重复的”继承IEqualityComparer接口,来重新实现一个“几乎完全相同的”的Compare类吗?

对于只有一个比较条件的简单情况,我们可以直接对 Distinct、Union、Except、Intersect 进行封装,简单通用方法:

 来源:C#list去重, https://www.cnblogs.com/hao-1234-1234/p/8855218.html

public class Compare<T, C> : IEqualityComparer<T>
    {
        private Func<T, C> _getField;
        public Compare(Func<T, C> getfield)
        {
            this._getField = getfield;
        }
        public bool Equals(T x, T y)
        {
            return EqualityComparer<C>.Default.Equals(_getField(x), _getField(y));
        }
        public int GetHashCode(T obj)
        {
            return EqualityComparer<C>.Default.GetHashCode(this._getField(obj));
        }
    }
    public static class CommonHelper
    {
        /// <summary>
        /// 自定义Distinct扩展方法
        /// </summary>
        /// <typeparam name="T">要去重的对象类</typeparam>
        /// <typeparam name="C">自定义去重的字段类型</typeparam>
        /// <param name="source">要去重的对象</param>
        /// <param name="getfield">获取自定义去重字段的委托</param>
        /// <returns></returns>
        public static IEnumerable<T> MyDistinct<T, C>(this IEnumerable<T> source, Func<T, C> getfield)
        {
            return source.Distinct(new Compare<T, C>(getfield));
        }
    }
然后这么使用:store1.MyDistinct(s=>s.Id).ToList();
Id 是用于较的属性(或字段),它是可以是任何一个属性。
4、多个比较条件 的通用方法如何实现?
类似于 store1.MyDistinct(s=>s.Id&&Name).ToList();

 四、微软官方文档

union :https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.enumerable.union?view=netframework-4.8

intersect:https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.enumerable.intersect?view=netframework-4.8

except:https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.enumerable.except?view=netframework-4.8

distinct:https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.enumerable.distinct?view=netframework-4.8

合交并差 核心代码是相同的: IEqualityComparer 。

建议在看看文档其它部分,以备后用,文档写的很棒!

 例如:join 某些情况与union等效。

五、交集、并集、差集、补集、对称差集 示意图,

 

 后两者后可以有前三者演变而来。补集可以求差或去重、对称差集可以先求差、在求并;

参考过的文章

https://www.oschina.net/code/snippet_222150_16997

http://www.cnblogs.com/flywing/p/5912242.html

https://blog.csdn.net/wizblack/article/details/78796557

 

树立目标,保持活力,gogogo!

标签:Product,return,C#,product,交并,集合,new,null,public
From: https://www.cnblogs.com/gzy2016Blog/p/18547868

相关文章

  • <a-modal>打开页面报错Ancestor with aria-hidden
    报错信息Blockedaria-hiddenonanelementbecauseitsdescendantretainedfocus.Thefocusmustnotbehiddenfromassistivetechnologyusers.Avoidusingaria-hiddenonafocusedelementoritsancestor.Considerusingtheinertattributeinstead,whichwi......
  • Modbus TCP转Modbus ASCII解决方案
    ModbusTCP和ModbusASCII是两种不同的通信协议。ModbusTCP是一种二进制协议,ModbusASCII是一种基于文本的协议。二者不能直接转换,因为它们的数据表示方式、消息结构、字符编码等都不相同。如果你需要将ModbusTCP转换为ModbusASCII,你需要先解析ModbusTCP消息,然后按照ModbusA......
  • Code128编码规则及示例
    编码格式​空白区域起始字符数据区域校验码结束字符空白区域所有字符条纹图像都是以黑色开始,白色结束,只有结束字符例外起始字符由于128码有三个字符集。所以有三个起始字符。 字符集包含字符值bsStartA全部大写字母和标点符号和特殊符号{2,1,1......
  • echart 环图
    option={tooltip:{trigger:'item'},legend:{type:'scroll',icon:'circle',orient:'vertical',left:'42%',itemGap:8,top:'middle',itemHeight:20,tooltip:{show:true},formatter......
  • 关于Spring生命周期控制的接口:SmartLifecycle
    在Spring框架中,SmartLifecycle接口和StopWatch类都是用来管理和监测应用行为的强大工具。SmartLifecycle提供了对Springbeans生命周期的细粒度控制,而StopWatch用于精确测量代码段的执行时间,对于性能分析和优化非常有用。下面,我们将结合SmartLifecycle和StopWatch......
  • Oracle用户管理模式下的备份恢复
    Oracle用户管理模式下的备份恢复1、用户管理模式下的冷备份1.1查询数据库相关信息查实例selectinstance_name,version,status,archiver,database_statusfromv$instance;查数据库selectdbid,name,log_modefromv$database;查数据文件状态selectfile_name,tabl......
  • unity3d————Resources异步加载
    知识点一:Resources异步加载是什么?在Unity中,资源加载可以分为同步加载和异步加载两种方式。同步加载会在主线程中直接进行,如果加载的资源过大,可能会导致程序卡顿,因为从硬盘读取数据到内存并进行处理是需要时间的。而异步加载则是Unity内部新开一个线程进行资源加载,这样就不会造......
  • libVLC倍速播放
    如何使用LibvlcSharp更改视频的播放速度_使用libVLCsharp流式播放pw保护的IP摄像头视频,但不播放视频_Libvlcsharp将在任何平台上播放特定的视频-腾讯云开发者社区-腾讯云 LibvlcSharp是一个基于libvlc的.NET绑定库,用于在应用程序中实现视频播放功能。要使用LibvlcSharp更改......
  • 国标GB28181软件LiteGBS国标GB28181-2022平台夜晚IPC灯光导致不能切换黑白模式且图像
    LiteGBS国标GB28181网页直播平台具有诸多显著特点。首先,它全力支持设备以GB28181协议接入,这意味着能够广泛接纳符合该协议标准的各类设备,为用户提供了丰富的设备选择空间。接入设备后,LiteGBS可对视频进行高效的解码、处理和分发等服务,确保视频信号的稳定传输和高质量呈现。在兼......
  • [ABC339G] Smaller Sum(分块 卡常 qwq)
    link和数列分块入门2差不多的思路,对每个块排序,然后就可以在上面二分,求和,发现都是在二分出来的位置前面的数,可以用前缀和预处理出来分块按照一般分法n,q同阶,时间复杂度是\(O(n\sqrt{n}\log\sqrt{n})\)然后交上去发现最后几个点T了,算一下,大概是2e5*450*8=7e8,时......