LINQ Union operator is used for finding unique elements between two sequences (Collections).
For example, suppose we have two collections A = { 1, 2, 3 }, and B = { 3, 4, 5 }. Union operator will find unique elements in both sequences. { 3 } element is available in both sequences. So union operator only takes one element in the result. C = { 1, 2, 3, 4, 5 }.
Union operator is only supported in Method syntax and not available in Query syntax.
Below is the syntax of Union operator:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer);
Union operator is an extension method whick takes second sequence as a parameter. Second overload takes instance of object that implements the IEqualityComparer interface.
C# LINQ Union Example in Method Syntax
string[] delhiResidents = { "Ramesh", "Kapil", "Vikas", "Amit" };
string[] kolkataResidents = { "Kapil", "Manmohan", "Deepak", "Amit" };
var allResidents = delhiResidents.Union(kolkataResidents);
foreach (var item in allResidents)
{
Console.WriteLine(item);
}
Result
-------
Ramesh
Kapil
Vikas
Amit
Manmohan
Deepak
In the above example, “Kapil” and “Amit” names are available in both delhiResidents and kolkataResidents collections classes. When we use Union operator it will take all elements but include “Kapil” and “Amit” at only one time.
Union Example with IEqualityComparer
By default, union operator does not work with Custom Types. It does not differentiate whether two types are equal or not. For this scenario, we need to create a new comparer class which implements IEqualityComparer interface. This interface has two methods Equals and GetHashCode. Both methods are compulsory to implement.
internal class Resident
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
}
internal class ResidentNameComparer : IEqualityComparer<Resident>
{
public bool Equals(Resident x, Resident y)
{
if (string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
public int GetHashCode(Resident obj)
{
return obj.Name.GetHashCode();
}
}
public static void Main(string[] args)
{
List<Resident> delhiResidents = new List<Resident>();
delhiResidents.Add(new Resident { Id = 1, Name = "Ramesh", City = "Delhi" });
delhiResidents.Add(new Resident { Id = 2, Name = "Kapil", City = "Delhi" });
delhiResidents.Add(new Resident { Id = 3, Name = "Vikas", City = "Delhi" });
delhiResidents.Add(new Resident { Id = 4, Name = "Amit", City = "Delhi" });
List<Resident> kolkataResidents = new List<Resident>();
kolkataResidents.Add(new Resident { Id = 5, Name = "Kapil", City = "Kolkata" });
kolkataResidents.Add(new Resident { Id = 6, Name = "Manmohan", City = "Kolkata" });
kolkataResidents.Add(new Resident { Id = 7, Name = "Deepak", City = "Kolkata" });
kolkataResidents.Add(new Resident { Id = 8, Name = "Amit", City = "Kolkata" });
var allResidents = delhiResidents.Union(kolkataResidents, new ResidentNameComparer());
foreach (var item in allResidents)
{
Console.WriteLine(item.Name);
}
}
Result
-------
Ramesh
Kapil
Vikas
Amit
Manmohan
Deepak
LINQ Union vs Concat
Both Union and Concat operators are used to append second sequence elements into the first sequence. But Union operator removes duplicates elements from the result.
Below is the example:
int[] A = { 1, 2, 3, 4 };
int[] B = { 3, 4, 5, 6 };
var resultOfUnion = A.Union(B);
var resultOfConcat = A.Concat(B);
Console.WriteLine("Union result");
foreach (var item in resultOfUnion)
{
Console.WriteLine("\t" + item);
}
Console.WriteLine("\nConcat result");
foreach (var item in resultOfConcat)
{
Console.WriteLine("\t" + item);
}
Result
------
Union result
1
2
3
4
5
6
Concat result
1
2
3
4
3
4
5
6
In both A and B collection, 3 and 4 numbers are available. As shown in the above result, Union takes one single 3 and 4 numbers but in result Concat takes 3 and 4 numbers two times.