-1

I have a Class named Privilegeswith 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

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
Mahmoud Zakal
  • 128
  • 3
  • 15

2 Answers2

4

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.

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
2

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();
Ahmad Ibrahim
  • 1,915
  • 2
  • 15
  • 32
  • 1
    I'd like to point that this solution is quite inefficient. More efficient solution should probably use [HashSet.Except](https://msdn.microsoft.com/en-us/library/bb908036(v=vs.90).aspx) and that `HashSet` should use a [custom comparer](http://stackoverflow.com/questions/1023424/how-to-use-comparer-for-a-hashset) that will ignore the value of `privilege`. – Eugene Podskal Jul 02 '16 at 21:07
  • i will see it but in the current time i will use this solution thanks anyway – Mahmoud Zakal Jul 02 '16 at 21:15