C# 对List<T>取指定条件下的差集

相关阅读1:Enumerable.Except 方法 (System.Linq) | Microsoft Docs 

相关阅读2:C# 对List<T>取交集、差集以及并集_起个名字好难啊-CSDN博客_c# list取交集

例如有下面这样一个对象

class Info
{
    public Info() { }

    public Info(string id, string name)
    {
        this.Id = id;
        this.Name = name;
    }

    public string Id { get; set; }

    public string Name { get; set; }
}

跟据上面对象生成两个List如下

 var listA = new List<Info>
 {
     new Info ("1","A"),
     new Info ("2","B"),
     new Info ("3","C"),
 };

 var listB = new List<Info>
 {
     new Info ("4","A"),
     new Info ("5","E"),
     new Info ("6","D"),
 };

我们期望找出listB中Name为(E)和(D)这两条不存在于listA中的数据

操作如下:

// 实现自定义比较器 
class
CtmComparer : IEqualityComparer<Info> { public bool Equals(Info x, Info y)=> x.Name == y.Name; // 这里仅根据Name作为依据,实际应用中比较复杂,但均可以实现自己的业务逻辑 public int GetHashCode([DisallowNull] Info obj) => obj == null ? 0: obj.ToString().GetHashCode(); }
// 使用Except取差集
var exceptResult = listB.Except(listA, new
CtmComparer()).ToList();

//
exceptResult :(5,E)、(6,D)

值得一提的是listB和listA的位置不同,结果也不同。

listB.Except(listA):取listB中,不存在于listA的元素,反之同理

 

完整示例代码:

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {

            var listA = new List<Info>
            {
                new Info ("1","A"),
                new Info ("2","B"),
                new Info ("3","C"),
            };

            var listB = new List<Info>
            {
                new Info ("4","A"),
                new Info ("5","E"),
                new Info ("6","D"),
            };

            var exceptResult = listB.Except(listA, new CtmComparer()).ToList();

            Console.ReadKey();
        }
    }

    class Info
    {
        public Info() { }

        public Info(string id, string name)
        {
            this.Id = id;
            this.Name = name;
        }

        public string Id { get; set; }

        public string Name { get; set; }
    }

    class CtmComparer : IEqualityComparer<Info> {
        public bool Equals(Info x, Info y)=> x.Name == y.Name;
        public int GetHashCode([DisallowNull] Info obj) => obj == null ? 0: obj.ToString().GetHashCode();
    }

}

上述代码中的比较器是单独写的class,如果你不想再写一个类,可以参考官方文档中的例子,直接在对象中继承 IEqualityComparer 来实现。

posted @ 2021-10-09 10:58  沄卿  阅读(838)  评论(0)    收藏  举报