IComparableVsICompareInterface.md - brainchildservices/curriculum GitHub Wiki

Slide 1

IComparable Vs IComparer Interface In C#

Q: How do we sort a list of integers?**

We just use the Sort method to sort the integer elements.

  using System;
  using System.Collections.Generic;

  public class Program
  {
      public static void Main()
      {
	      List<int> intList = new List<int>() {1, 4, 2, 6, 7, 12, 34, 11, 20, 30};
	
	      foreach (int item in intList)
	      {
		      Console.Write(item + " ");
	      }

	      intList.Sort();
	
	      Console.WriteLine("\n\nSorted List of integers:\n");
	      foreach (int item in intList)
	      {
		      Console.Write(item + " ");
	      }
      }
  }

Slide 2

Q: How do we Sort a User Defined User Defined List of objects?

We have a student class with few properties. We create list of Student objects and Add it to StudentList in the main method.

 using System;
 using System.Collections.Generic;

 public class Student
 {
     public string Name { get; set; }
     public int Age { get; set; }
     public double Mark { get; set; }
     public char Grade { get; set; }
     public int Id { get; set; }

     public Student(string name, int age, double mark, char grade, int id)
     {
	     Name = name;
	     Age = age;
	     Mark = mark;
	     Grade = grade;
	     Id = id;
     }
 }

 public class Program
 {
     public static void Main()
     {
	     List<Student> StudentList = new List<Student>();
	
	     StudentList.Add(new Student("Chris", 23, 75, 'C', 1015));
	     StudentList.Add(new Student("Jeff", 22, 98, 'A', 1022));
	     StudentList.Add(new Student("Mike", 21, 80, 'C', 1021));
	     StudentList.Add(new Student("Amar", 20, 85, 'B', 1011));
	     StudentList.Add(new Student("Aron", 25, 100, 'A', 1011));
	
	     Console.WriteLine("Name    Age  Mark  Grade   ID\n");
	     foreach (Student item in StudentList)
	     {
		     Console.WriteLine("{0,5}{1,5}{2,5}{3,5}{4,10}", item.Name, item.Age, item.Mark, item.Grade, item.Id);	//Formatting the table view by providing the number of space after the argument No:
	     }
     }
 }

Slide 3

Let's see what happens when we try to sort the StudentList.

  using System;
  using System.Collections.Generic;

  public class Student
  {
      public string Name { get; set; }
      public int Age { get; set; }
      public double Mark { get; set; }
      public char Grade { get; set; }
      public int Id { get; set; }

      public Student(string name, int age, double mark, char grade, int id)
      {
	      Name = name;
	      Age = age;
	      Mark = mark;
	      Grade = grade;
	      Id = id;
      }
  }

  public class Program
  {
      public static void Main()
      {
	      List<Student> StudentList = new List<Student>();
	
	      StudentList.Add(new Student("Chris", 23, 75, 'C', 1015));
	      StudentList.Add(new Student("Jeff", 22, 98, 'A', 1022));
	      StudentList.Add(new Student("Mike", 21, 80, 'C', 1021));
	      StudentList.Add(new Student("Amar", 20, 85, 'B', 1011));
	      StudentList.Add(new Student("Aron", 25, 100, 'A', 1011));
	
	      foreach (Student item in StudentList)
	      {
		      Console.WriteLine("{0}  {1}  {2}  {3}  {4}",item.Name, item.Age, item.Mark, item.Grade, item.Id);
	      }
	
	      StudentList.Sort();		//Sorting the Student List leads to error: System.InvalidOperationException: Failed to compare two elements in the array.

      }
  }

Error: System.InvalidOperationException: Failed to compare two elements in the array. System.ArgumentException: At least one object must implement IComparable.

For the ordered data types like numbers or strings, comparison can be done easily.
As there can be many different data members for the object, comparison of two objects cannot be done directly.

Slide 4

IComparable

We can see from the error that it is asking to implement IComparable.

IComparable interface is used to sort elements and compare the current instance with another object of the same type. The CompareTo method of the IComparable interface returns an int value that shows how two elements are related.

  • Sorting the List objects by ID:

    using System;
    using System.Collections.Generic;
    
    public class Student : IComparable<Student>			//Inherit the Interface IComparable that takes Student as object
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public double Mark { get; set; }
        public char Grade { get; set; }
        public int Id { get; set; }
    
        public Student(string name, int age, double mark, char grade, int id)
        {
            Name = name;
            Age = age;
            Mark = mark;
            Grade = grade;
            Id = id;
        }
    
        public int CompareTo(Student Std)		//Implement CompareTo method and pass the next Student object
        {
            if (this.Id == Std.Id)		//If the current instance value and the next values are same return 0. No swap done 
      	      return 0;
            else if (this.Id > Std.Id)	//If the current instance value is greater than the next value, return 1 so that so that swap is done
      	      return 1;			//That is, put the next value infront the curret value(swap the places)
            else
      	      return -1;		//If the current instance value is less than the next value, return -1 so that no swap is performed
        }
    }
    
    public class Program
    {
        public static void Main()
        {
            List<Student> StudentList = new List<Student>();
            StudentList.Add(new Student("Chris", 23, 75, 'C', 1015));
            StudentList.Add(new Student("Jeff", 22, 98, 'A', 1022));
            StudentList.Add(new Student("Mike", 21, 80, 'C', 1021));
            StudentList.Add(new Student("Amar", 20, 85, 'B', 1011));
            StudentList.Add(new Student("Aron", 25, 100, 'A', 1011));
    
            StudentList.Sort(); 	//The Sort Method now calls the CompareTo and uses it to Sort the Student List.
      
            Console.WriteLine("Name    Age  Mark  Grade   ID\n");
            foreach (Student item in StudentList)
            {
      	      Console.WriteLine("{0,5}{1,5}{2,5}{3,5}{4,10}", item.Name, item.Age, item.Mark, item.Grade, item.Id);
            }
        }
    }
    

Slide 5

  • Sorting the List objects by Name:
    Comparing Strings Eg:

    using System;
    
    public class Program
    {
        public static void Main()
        {
            string name1 = "Ajosh";
            string name2 = "Bjosh";
            string name3 = "Ajosh";
      
            Console.WriteLine("Second value is greater than first: " + String.Compare(name1, name2));
            Console.WriteLine("First value is greater than second: " + String.Compare(name2, name1));
            Console.WriteLine("First value and second value are equal: " + String.Compare(name1, name3));
        }
    }
    

Slide 5 Downwards

Sorting the List objects by Name

  using System;
  using System.Collections.Generic;

  public class Student : IComparable<Student>			
  {
      public string Name { get; set; }
      public int Age { get; set; }
      public double Mark { get; set; }
      public char Grade { get; set; }
      public int Id { get; set; }

      public Student(string name, int age, double mark, char grade, int id)
      {
	      Name = name;
	      Age = age;
	      Mark = mark;
	      Grade = grade;
	      Id = id;
      }

      public int CompareTo(Student Std)		
      {
	      return String.Compare(this.Name, Std.Name);			//Using String.Compare to Sort the List by Name
      }
  }

  public class Program
  {
      public static void Main()
      {
	      List<Student> StudentList = new List<Student>();
	      StudentList.Add(new Student("Chris", 23, 75, 'C', 1015));
	      StudentList.Add(new Student("Jeff", 22, 98, 'A', 1022));
	      StudentList.Add(new Student("Mike", 21, 80, 'C', 1021));
	      StudentList.Add(new Student("Amar", 20, 85, 'B', 1011));
	      StudentList.Add(new Student("Aron", 25, 100, 'A', 1011));

	      StudentList.Sort(); 	
	
	      Console.WriteLine("Name    Age  Mark  Grade   ID\n");
	      foreach (Student item in StudentList)
	      {
		      Console.WriteLine("{0,5}{1,5}{2,5}{3,5}{4,10}", item.Name, item.Age, item.Mark, item.Grade, item.Id);
	      }
      }
  } 

Slide 6

IComparer Interface:

IComparable is going to help until you have complete control of user-defined class, but let's say you want to apply sorting on a class on which you don't have control. Meaning you can't change the implementation of a class; e.g., when you access some class from DLL, you can use them but you can't change their implementation.

In order to achieve sorting on such classes, the IComparer interface is used.

Slide 7

IComparer interface has method Compare. This method compares two objects and returns a value indicating whether one is less than, equal to or greater than other.

  1. Create a class that inherits IComparer interface

  2. Implement the method Compare in the created class to return an int value

  3. Create object of the class

  4. The overloads of the Method Sort can take IComparer. So pass the created object as parameter to the Sort method.

    using System; using System.Collections.Generic;

    public class Student //We are not allowed to make any changes to the class Student { public string Name { get; set; } public int Age { get; set; } public double Mark { get; set; } public char Grade { get; set; } public int Id { get; set; }

       public Student(string name, int age, double mark, char grade, int id)
       {
           Name = name;
           Age = age;
           Mark = mark;
           Grade = grade;
           Id = id;
       }
    

    }

    public class CompareStudents : IComparer //Creating a class CompareStudents that inherits IComparer class { public int Compare(Student std1, Student std2) //Implementing Compare method that has two objects to compare as its parameters. { if (std1.Id == std2.Id) //The logic for Compare method is same as the one use for CompareTo Method return 0; //Changes are that instead of comparing with the current instance, else if (std1.Id > std2.Id) //We compare between the object parameters. return 1; else return -1; } }

    public class Program { public static void Main() { List StudentList = new List(); StudentList.Add(new Student("Chris", 23, 75, 'C', 1015)); StudentList.Add(new Student("Jeff", 22, 98, 'A', 1022)); StudentList.Add(new Student("Mike", 21, 80, 'C', 1021)); StudentList.Add(new Student("Amar", 20, 85, 'B', 1011)); StudentList.Add(new Student("Aron", 25, 100, 'A', 1011));

           CompareStudents cmprStds = new CompareStudents(); 	//Create an object of the CompareStudents class
     
           StudentList.Sort(cmprStds); 				//Pass object of the CompareStudents to the Sort method.
     
           Console.WriteLine("Name    Age  Mark  Grade   ID\n");
           foreach (Student item in StudentList)
           {
     	      Console.WriteLine("{0,5}{1,5}{2,5}{3,5}{4,10}", item.Name, item.Age, item.Mark, item.Grade, item.Id);
           }
       }
    

    }

Slide 8

Exercises:

  1. Write a program to create a List of class Employee.
    Employee class has properties: Name(string), age(short), Identity(int) , DOB(DateTime), Designation(string)
    Create a List of employees, Add new employees.
    Use IComparable interface to Sort by Name, Age, Identity, DOB and Designation.
    Print results to show result of sorting by each field.

Slide 9

  1. Write a program to create a List of class Student. Studentclass has properties: Name(string), age(short), Marks(int) , grade(char) Create a List of Student, Add new Students.
    Use IComparer interface to Sort by Name, age, Marks, grade Print results to show result of sorting by each field.

References:
https://www.c-sharpcorner.com/article/icomparable-vs-icomparer-interface-in-c-sharp/
https://www.csharpstar.com/difference-between-icomparable-and-icomparer-interface-csharp/
https://www.youtube.com/watch?v=aBXoqJRMToQ&t=809s
https://stackoverflow.com/questions/10160770/how-to-print-list-as-table-in-console-application
https://www.c-sharpcorner.com/UploadFile/mahesh/compare-strings-in-C-Sharp/

⚠️ **GitHub.com Fallback** ⚠️