The Except method returns the set of items which are contained in the first collection but are not contained in the second. The default IEqualityComparer
is used to compare the items within the two sets. There is an overload which accepts an IEqualityComparer
as an argument.
Example:
int[] first = { 1, 2, 3, 4 };
int[] second = { 0, 2, 3, 5 };
IEnumerable<int> inFirstButNotInSecond = first.Except(second);
// inFirstButNotInSecond = { 1, 4 }
Output:
1
4
In this case .Except(second)
excludes elements contained in the array second
, namely 2 and 3 (0 and 5 are not contained in the first
array and are skipped).
Note that Except
implies Distinct
(i.e., it removes repeated elements). For example:
int[] third = { 1, 1, 1, 2, 3, 4 };
IEnumerable<int> inThirdButNotInSecond = third.Except(second);
// inThirdButNotInSecond = { 1, 4 }
Output:
1
4
In this case, the elements 1 and 4 are returned only once.
Implementing IEquatable
or providing the function an IEqualityComparer
will allow using a different method to compare the elements.
Note that the GetHashCode
method should also be overridden so that it will return an identical hash code for object
that are identical according to the IEquatable
implementation.
Example With IEquatable:
class Holiday : IEquatable<Holiday>
{
public string Name { get; set; }
public bool Equals(Holiday other)
{
return Name == other.Name;
}
// GetHashCode must return true whenever Equals returns true.
public override int GetHashCode()
{
//Get hash code for the Name field if it is not null.
return Name?.GetHashCode() ?? 0;
}
}
public class Program
{
public static void Main()
{
List<Holiday> holidayDifference = new List<Holiday>();
List<Holiday> remoteHolidays = new List<Holiday>
{
new Holiday { Name = "Xmas" },
new Holiday { Name = "Hanukkah" },
new Holiday { Name = "Ramadan" }
};
List<Holiday> localHolidays = new List<Holiday>
{
new Holiday { Name = "Xmas" },
new Holiday { Name = "Ramadan" }
};
holidayDifference = remoteHolidays
.Except(localHolidays)
.ToList();
holidayDifference.ForEach(x => Console.WriteLine(x.Name));
}
}
Output:
Hanukkah