Home » c# » Difference between two lists

Difference between two lists

Posted by: admin November 29, 2017 Leave a comment

Questions:

I Have two generic list filled with CustomsObjects.

I need to retrieve the difference between those two lists(Items who are in the first without the items in the second one) in a third one.

I was thinking using .Except() was a good idea but I don’t see how to use this..
Help!

Answers:

Using Except is exactly the right way to go. If your type overrides Equals and GetHashCode, or you’re only interested in reference type equality (i.e. two references are only “equal” if they refer to the exact same object), you can just use:

var list3 = list1.Except(list2).ToList();

If you need to express a custom idea of equality, e.g. by ID, you’ll need to implement IEqualityComparer<T>. For example:

public class IdComparer : IEqualityComparer<CustomObject>
{
    public int GetHashCode(CustomObject co)
    {
        if (co == null)
        {
            return 0;
        }
        return co.Id.GetHashCode();
    }

    public bool Equals(CustomObject x1, CustomObject x2)
    {
        if (object.ReferenceEquals(x1, x2))
        {
            return true;
        }
        if (object.ReferenceEquals(x1, null) ||
            object.ReferenceEquals(x2, null))
        {
            return false;
        }
        return x1.Id == x2.Id;
    }
}

Then use:

var list3 = list1.Except(list2, new IdComparer()).ToList();

EDIT: As noted in comments, this will remove any duplicate elements; if you need duplicates to be preserved, let us know… it would probably be easiest to create a set from list2 and use something like:

var list3 = list1.Where(x => !set2.Contains(x)).ToList();

Questions:
Answers:

You could do something like this:

var result = customlist.Where(p => !otherlist.Any(l => p.someproperty == l.someproperty));

Questions:
Answers:
var third = first.Except(second);

(you can also call ToList() after Except(), if you don’t like referencing lazy collections.)

The Except() method compares the values using the default comparer, if the values being compared are of base data types, such as int, string, decimal etc.

Otherwise the comparison will be made by object address, which is probably not what you want… In that case, make your custom objects implement IComparable (or implement a custom IEqualityComparer and pass it to the Except() method).

Questions:
Answers:

If both your lists implement IEnumerable interface you can achieve this using LINQ.

list3 = list1.where(i => !list2.contains(i));

Questions:
Answers:

Since the Except extension method operates on two IEumerables, it seems to me that it will be a O(n^2) operation. If performance is an issue (if say your lists are large), I’d suggest creating a HashSet from list1 and use HashSet’s ExceptWith method.

Questions:
Answers:

bit late but here is working solution for me

 var myBaseProperty = (typeof(BaseClass)).GetProperties();//get base code properties
                    var allProperty = entity.GetProperties()[0].DeclaringType.GetProperties();//get derived class property plus base code as it is derived from it
                    var declaredClassProperties = allProperty.Where(x => !myBaseProperty.Any(l => l.Name == x.Name)).ToList();//get the difference

In above mention code I am getting the properties difference between my base class and derived class list

Questions:
Answers:
        List<int> list1 = new List<int>();
        List<int> list2 = new List<int>();
        List<int> listDifference = new List<int>();

        foreach (var item1 in list1)
        {
            foreach (var item2 in list2)
            {
                if (item1 != item2)
                    listDifference.Add(item1);
            }
        }