Introduction
Here, you will learn the uses of Union, Intersect, Except, and their differences. To get a clear picture, we will use examples.
Prerequisites
- Visual Studio
- Basics of LINQ and C#
Article flow
- Use of Union
- Use of Intersect
- Use of Except
- Use of Distinct
- Difference between Union, Intersect, Distinct, and Except
Use of Union
Union is an extension method to merge two collections. It requires at least two collections to perform the merge operation, but that merged collection holds only the distinct elements from both the collections. For better understanding, we will use an example.
First, we will go with a simple example, for that I created two lists
- List<int> collectionOne = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- List<int> collectionTwo = new List<int>() { 1, 2, 3, 11, 12, 13, 14, 15 };
- var unionResult = collectionOne.Union(collectionTwo);
- foreach (var item in unionResult)
- {
- Console.Write(item +" ");
- }
Now run your application
Detailed Description
In above result you can see the elements are unique because union removed the repeated/duplicate elements from both collections/ list. Now we got a clear picture about union, the union is used to return the distinct elements from both collections. Now we will use a complex example, and for that I have created a class below and made two list with values
- public class Employee {
- public int ID {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- public string Designation {
- get;
- set;
- }
- public double Salary {
- get;
- set;
- }
- }
- List < Employee > employeeCollection1 = new List < Employee > () {
- new Employee() {
- ID = 1, Name = "Gnanavel Sekar", Designation = "Software Engineer", Salary = 150000
- },
- new Employee() {
- ID = 2, Name = "Subash S", Designation = "Software Engineer", Salary = 170000
- },
- new Employee() {
- ID = 3, Name = "Robert A", Designation = "Application Developer", Salary = 180000
- },
- new Employee() {
- ID = 4, Name = "Ammaiyappan", Designation = "Software Developer", Salary = 120000
- }
- };
- List < Employee > employeeCollection2 = new List < Employee > () {
- new Employee() {
- ID = 1, Name = "Gnanavel Sekar", Designation = "Software Engineer", Salary = 150000
- },
- new Employee() {
- ID = 3, Name = "Robert A", Designation = "Application Developer", Salary = 180000
- },
- new Employee() {
- ID = 4, Name = "Ammaiyappan", Designation = "Software Developer", Salary = 120000
- },
- new Employee() {
- ID = 5, Name = "Ramar A", Designation = "Tech Lead", Salary = 200000
- }
- };
- var unionComplexResult = employeeCollection1.Union(employeeCollection2);
- Console.WriteLine(System.Environment.NewLine + "Complex Union");
- foreach(var item in unionComplexResult) {
- Console.WriteLine("ID :" + item.ID + " Name :" + item.Name + " Designation :" + item.Designation + " Salary :" + item.Salary);
- }
Now run your application to see the result
In the above result you can see, there are the duplicate values, the union extend method doesn't perform its unique operation with large collections because it doesn't know which field to compare, so we need to specify which field to compare. To overcome this problem "IEqualityComparer" interface
Union with IEqualityComparer
When we work with IEqualityComparer we need to specify the field to compare. For that I have created on class which implements the iequalitycomparer interface and overrides the equals method
- public class EmployeeComparer: IEqualityComparer < Employee > {
- public bool Equals(Employee emp1, Employee emp2) {
- if (emp1.ID == emp2.ID && emp1.Name.ToString().ToUpper() == emp2.Name.ToString().ToUpper()) {
- return true;
- }
- return false;
- }
- }
In above class we mentioned to compare the Employee ID and Name from those collections
Now we need mention the class in union extension method which implements IEqualityComparer interface, here we implmented in EmployeeComparer class,
- var unionComplexResultWithIEquality = employeeCollection1.Union(employeeCollection2, new EmployeeComparer());
- foreach(var item in unionComplexResultWithIEquality)
- {
- Console.WriteLine("ID :" + item.ID + " Name :" + item.Name + " Designation :" + item.Designation + " Salary :" + item.Salary);
- }
Now see the result with Iequalitycomparer. See the below screen the results are with the distinct elements from those collections.
Now we got a clear picture about Union operator in linq, it's used to merge the two collections and returns distinct elements from those collection sand we need to implment the IEqualitycomparer while we work with huge amounts of data.
Use of Intersect
Intersect Method is a extension to method and it requires two collections to return common pattern/element from both the collection. First we will go with simple example to get idea about this. For that I created two integer collections.
- List<int> collectionOne = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- List<int> collectionTwo = new List<int>() { 1, 2, 3, 11, 12, 13, 14, 15 };
- Console.WriteLine(System.Environment.NewLine + "Intersect");
- var IntersectResult = collectionOne.Intersect(collectionTwo);
- foreach (var item in IntersectResult)
- {
- Console.WriteLine(item);
- }
Result In the above result you can see that common values are only returned from those collections, for better understanding shall we move with large collection values?, for that I have created employee class and I made two lists with values.
- List < Employee > employeeCollection1 = new List < Employee > () {
- new Employee() {
- ID = 1, Name = "Gnanavel Sekar", Designation = "Software Engineer", Salary = 150000
- },
- new Employee() {
- ID = 2, Name = "Subash S", Designation = "Software Engineer", Salary = 170000
- },
- new Employee() {
- ID = 3, Name = "Robert A", Designation = "Application Developer", Salary = 180000
- },
- new Employee() {
- ID = 4, Name = "Ammaiyappan", Designation = "Software Developer", Salary = 120000
- }
- };
- List < Employee > employeeCollection2 = new List < Employee > () {
- new Employee() {
- ID = 1, Name = "Gnanavel Sekar", Designation = "Software Engineer", Salary = 150000
- },
- new Employee() {
- ID = 3, Name = "Robert A", Designation = "Application Developer", Salary = 180000
- },
- new Employee() {
- ID = 4, Name = "Ammaiyappan", Designation = "Software Developer", Salary = 120000
- },
- new Employee() {
- ID = 5, Name = "Ramar A", Designation = "Tech Lead", Salary = 200000
- }
- };
- var intersectComplexResult = employeeCollection1.Intersect(employeeCollection2);
- Console.WriteLine(System.Environment.NewLine + "Complex Intersect");
- foreach(var item in intersectComplexResult) {
- Console.WriteLine("ID :" + item.ID + " Name :" + item.Name + " Designation :" + item.Designation + " Salary :" + item.Salary);
- }
Now see the result,
It doesn't return any value, why? Because it doesn't know howto compare, there is no issue while we have a single column value in the collection but here we have more than one column so that it can't compare, so shall we specify the fields to compare? We can overcome this issue by using IEqualityComparer. Okay we will use an example
Intersect with IEqualityComparer
- public class EmployeeComparer: IEqualityComparer < Employee > {
- public bool Equals(Employee emp1, Employee emp2) {
- if (emp1.ID == emp2.ID && emp1.Name.ToString().ToUpper() == emp2.Name.ToString().ToUpper()) {
- return true;
- }
- return false;
- }
- public int GetHashCode(Employee obj) {
- return obj.ID.GetHashCode();
- }
- }
In above "EmployeeComparer" class implmented the IEqualityComparer Interface and here we said to compare the employee ID and Name
- var intersectEqualityComplexResult = employeeCollection1.Intersect(employeeCollection2,new EmployeeComparer());
- Console.WriteLine(System.Environment.NewLine + "Complex Intersect with Equality");
- foreach (var item in intersectEqualityComplexResult)
- {
- Console.WriteLine("ID :" + item.ID + " Name :" + item.Name + " Designation :" + item.Designation + " Salary :" + item.Salary);
- }
Result
in above result we got the common pattern from those collection by using IEqualitycomparer, Now we got the clear picture about Intersect, it's used to return the common pattern from both collections and we need to use the IEqualitycomparer while we working with large collections.
Use of Except Except method is a extension method to return a first collection which doesn't exist in second collection, it also requires two collections to perform its unique actions, let's see the example
- List<int> collectionOne = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- List<int> collectionTwo = new List<int>() { 1, 2, 3, 11, 12, 13, 14, 15 };
- Console.WriteLine(System.Environment.NewLine + "Except");
- var exceptResult = collectionOne.Except(collectionTwo);
- foreach (var item in exceptResult)
- {
- Console.WriteLine(item + " ");
- }
Result
See the result: We got the first collection value which does not exist in the second collection. Now we'll go with large collection values
- List < Employee > employeeCollection1 = new List < Employee > () {
- new Employee() {
- ID = 1, Name = "Gnanavel Sekar", Designation = "Software Engineer", Salary = 150000
- },
- new Employee() {
- ID = 2, Name = "Subash S", Designation = "Software Engineer", Salary = 170000
- },
- new Employee() {
- ID = 3, Name = "Robert A", Designation = "Application Developer", Salary = 180000
- },
- new Employee() {
- ID = 4, Name = "Ammaiyappan", Designation = "Software Developer", Salary = 120000
- }
- };
- List < Employee > employeeCollection2 = new List < Employee > () {
- new Employee() {
- ID = 1, Name = "Gnanavel Sekar", Designation = "Software Engineer", Salary = 150000
- },
- new Employee() {
- ID = 3, Name = "Robert A", Designation = "Application Developer", Salary = 180000
- },
- new Employee() {
- ID = 4, Name = "Ammaiyappan", Designation = "Software Developer", Salary = 120000
- },
- new Employee() {
- ID = 5, Name = "Ramar A", Designation = "Tech Lead", Salary = 200000
- }
- };
- var ExceptComplexResult = employeeCollection1.Except(employeeCollection2);
- Console.WriteLine(System.Environment.NewLine + "Complex Except");
- foreach(var item in ExceptComplexResult) {
- Console.WriteLine("ID :" + item.ID + " Name :" + item.Name + " Designation :" + item.Designation + " Salary :" + item.Salary);
- }
Result
See the above result. We got the wrong result because it cannot handle the large collections and it doesn't know which field to compare. To overcome this issue we need to go with IEqualityComparer. For that I have created the EmployeeComparer class, which implements the IEqualityComparer interface to compare exact fields.
Except with IEqualityComparer
- public class EmployeeComparer: IEqualityComparer < Employee > {
- public bool Equals(Employee emp1, Employee emp2) {
- if (emp1.ID == emp2.ID && emp1.Name.ToString().ToUpper() == emp2.Name.ToString().ToUpper()) {
- return true;
- }
- return false;
- }
- public int GetHashCode(Employee obj) {
- return obj.ID.GetHashCode();
- }
- }
We need to access the EmployeeComparer class in the following way
-
- var ExceptComplexResultWithIEquality = employeeCollection1.Except(employeeCollection2, new EmployeeComparer());
- foreach (var item in ExceptComplexResultWithIEquality)
- {
- Console.WriteLine("ID :" + item.ID + " Name :" + item.Name + " Designation :" + item.Designation + " Salary :" + item.Salary);
- }
Result
Now you see the exact result, it returned the first collection value which doesn't exist in the second collection
Use of Distinct This method is used to return the unique element(s) from the respective collection. For better understanding I have created two lists with string and integer types.
- List<string> nameList = new List<string>() { "Gnanavel Sekar", "Subash S", "Robert", "Gnanavel Sekar", "Subash S" };
- List<int> idList = new List<int>() { 1, 2, 3, 2, 4, 4, 3, 5 };
- var stringCollection = nameList.Distinct();
- foreach (var str in stringCollection)
- {
- Console.WriteLine(str);
- }
- var integerCollection = idList.Distinct();
- foreach (var i in integerCollection)
- {
- Console.WriteLine(i);
- }
Now run your application
Now we got the clear picture about Distinct, it's used to return the unique value from the respective collection
Difference between Union,Intersect, Except and Distinct
Union | Intersect | Except | Distinct |
It returns the unique (or) distinct element from both collection. | It returns the common element from both collection | It returns the fist collection element which doesn't exist in the second collection | It returns the distinct element from the respective collection |
It requires two collections | It requires two collections | It requires two collections | It requires single collection |
Summary
In this article you learned the uses of Union, Intersect, Except, Distinct and the respective differences. I hope it was helpful, your comments and feedback are always welcome.