从两个列表中获取匹配和不匹配的元素

本文关键字:不匹配 元素 获取 列表 两个 | 更新日期: 2023-09-27 17:54:38

我有一个名为Privileges的类,具有以下属性int UserId,string FormName,string CompName,int Privilege

我有两个不同值的Privileges类型列表作为下面的样本

List<Privileges> list1 = new List<Privileges>(){
            new Privileges(){UserId= 1,FormName="Form1",CompName="Button1",Privilege=2},
            new Privileges(){UserId= 2,FormName="Form1",CompName="Button3",Privilege=3},
            new Privileges(){UserId= 3,FormName="Form2",CompName="Button2",Privilege=2}
        };
        List<Privileges> list2 = new List<Privileges>(){
            new Privileges(){UserId= 5,FormName="Form1",CompName="Button1",Privilege=2},
            new Privileges(){UserId= 2,FormName="Form1",CompName="Button3",Privilege=4},
            new Privileges(){UserId= 4,FormName="Form2",CompName="Button2",Privilege=3}
        };

我想生成3个函数
我做了第一个返回两个列表之间匹配的元素结果如下

{UserId= 2,FormName="Form1",CompName="Button3",Privilege=3}

第二个函数应该返回存在于第一个列表而不存在于第二个列表的元素,结果如下

{UserId= 1,FormName="Form1",CompName="Button1",Privilege=2},
{UserId= 3,FormName="Form2",CompName="Button2",Privilege=2}

第三个函数应该返回存在于第二个列表而不存在于第一个列表中的元素,结果如下

{UserId= 5,FormName="Form1",CompName="Button1",Privilege=2},
{UserId= 4,FormName="Form2",CompName="Button2",Privilege=3}

无论privilege的值是多少,匹配子句都应该比较UserId,FormName,CompName的值。

你可以在这里查看我的代码片段

从两个列表中获取匹配和不匹配的元素

您不必为这些(以及更多)任务编写任何复杂的LINQ语句。只要定义一个IEqualityComparer,一切都变得非常简单:

class PrivilegesComparer : IEqualityComparer<Privileges>
{
    public bool Equals(Privileges x, Privileges y)
    {
        return x.UserId == y.UserId
               && x.FormName == y.FormName
               && x.CompName == y.CompName;
    }
    public int GetHashCode(Privileges obj)
    {
        return (obj.UserId + obj.FormName + obj.CompName).GetHashCode();
    }
}

用法:

var comparer = new PrivilegesComparer();
var intersect = list1.Intersect(list2, comparer);
var l1Exceptl2 = list1.Except(list2, comparer);
var l2Exceptl1 = list2.Except(list1, comparer);

分别表示第一个、第二个和第三个函数。

这与为每个单独的任务编写复杂的LINQ语句是完全不同的。

list1中的元素不在list2

var itemsInList1NotInList2 = list1.Where(l1 => !list2.Any(l2 => l1.UserId == l2.UserId && l1.FormName == l2.FormName && l1.CompName == l2.CompName)).ToList();

list2中的元素不在list1

var itemsInList2NotInList1 = list2.Where(l2 => !list1.Any(l1 => l1.UserId == l2.UserId && l1.FormName == l2.FormName && l1.CompName == l2.CompName)).ToList();