简体   繁体   中英

Get matched and unmatched elements from 2 lists

I have a Class named Privileges with the following properties int UserId,string FormName,string CompName,int Privilege

And I have 2 lists of Privileges type with different values as the sample below

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}
        };

I want to make 3 functions
I made the first one which returns matched elements between the 2 lists and the result is the following

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

The 2nd function should return elements that exist in the first list and not in the second list, with the following result

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

The 3rd function should return elements that exist in the second list and not in the first list, with the following result

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

The matching clause should compare UserId,FormName,CompName values regardless what the value of privilege is.

you can check my code snippet here

You don't have to write any complex LINQ statements for these (and many more) tasks. Just define an IEqualityComparer and everything becomes almost ridiculously simple:

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();
    }
}

Usage:

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

Which represent your first, second and third function, respectively.

That's quite different from writing a complex LINQ statement for each individual task.

Elements in list1 not in list2

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

Elements in list2 not in list1

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM