C basic array sorting object size comparison implementation code

  • 2020-05-07 20:17:07
  • OfStack

Let's start with a small example:
 
int[] intArray = new int[]{2,3,6,1,4,5}; 
Array.Sort(intArray); 
Array.ForEach<int>(intArray,(i)=>Console.WriteLine(i)); 

This example defines an int array, then USES the Array.Sort (arr) static method to sort the array, and finally outputs the sorted array. The above examples will, unsurprisingly, output 1,2,3,4,5,6 in turn.
Why does Array's Sort method sort the int array correctly? Can we customize the class? Try the following code:
 
public class Student 
{ 
public int Age { get; set; } 
public string Name { get; set; } 
public int Score { get; set; } 
} 
static void Main(string[] args) 
{ 
Student[] students = new Student[]{ 
new Student(){Age = 10,Name=" zhang 3",Score=70}, 
new Student(){Age = 12,Name=" li 4",Score=97}, 
new Student(){Age = 11,Name=" The king 5",Score=80}, 
new Student(){Age = 9,Name=" zhao 6",Score=66}, 
new Student(){Age = 12,Name=" Si ma ",Score=90}, 
}; 
Console.WriteLine("-------------- Default sort output --------"); 
Array.Sort(students); 
Array.ForEach<Student>(students,(s)=>Console.WriteLine(string.Format("{0}{1,2} At the age of 18, his score is {2,3}",s.Name,s.Age,s.Score))); 
Console.Read(); 
} 

We define the Student class and then sort its array as well. The program is correctly compiled and passed, but there is an error in running. The exception is thrown: System.InvalidOperationException {"Failed to compare two two in the array "}, the InnerException of this exception is ArgumentException{"At least one object implement IComparable "}; Runtime exception: to use the Array.Sort (arr) static method, we must ensure that there is one element in the array to implement the IComparable interface. In this case, let's let the Student class implement the IComparable interface.
 
public class Student :IComparable 
{ 
public int Age { get; set; } 
public string Name { get; set; } 
public int Score { get; set; } 
/// <summary> 
///  implementation IComparable Interface with Age compare  
/// </summary> 
/// <param name="obj"> Comparison of object </param> 
/// <returns> Compare the results </returns> 
public int CompareTo(object obj) 
{ 
if (obj is Student) 
{ 
return Age.CompareTo(((Student)obj).Age); 
} 
return 1; 
} 
} 

IComparable interface is implemented in Student class, Age attribute of Student is compared in CompareTo method, this one time compiles again to run, the program normally outputs Student array sorted by age.
What if we were to sort the Score attribute of Student? The Student class implements an IComparable interface that can only be sorted by one property.
This is very easy to implement.net's library developers have already prepared another interface IComparer for us < T > The interface is used to compare two instances of type T. The following StudentScoreComparer class implements IComparer compared to Student according to the Score attribute < Student >
 
public class StudentScoreComparer : IComparer<Student> 
{ 
public int Compare(Student x, Student y) 
{ 
return x.Score.CompareTo(y.Score); 
} 
} 

Now we can sort the Student array by Score attributes using the following code:
 
Console.WriteLine("---------- Sort the output by score ------------"); 
Array.Sort(students, new StudentScoreComparer()); 
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2} At the age of 18, his score is {2,3}", s.Name, s.Age, s.Score))); 

But 1 simple sort according to Score attribute, and then define 1 class is not a little bit big, there is a better way? Of course. net has prepared Comparison for us to compare the size of objects < T > We can use ramda expression or anonymous delegate to directly sort, as follows:
 
Console.WriteLine("---------- Sort the output by score ----------"); 
Array.Sort(students, (s1, s2) => s1.Score.CompareTo(s2.Score)); 
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2} At the age of 18, his score is {2,3}", s.Name, s.Age, s.Score))); 

The complete code example is as follows:
 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
namespace SortingInCSharp 
{ 
class Program 
{ 
public class Student : IComparable 
{ 
public int Age { get; set; } 
public string Name { get; set; } 
public int Score { get; set; } 
/// <summary> 
///  implementation IComparable Interface with Age compare  
/// </summary> 
/// <param name="obj"> Comparison of object </param> 
/// <returns> Compare the results </returns> 
public int CompareTo(object obj) 
{ 
if (obj is Student) 
{ 
return Age.CompareTo(((Student)obj).Age); 
} 
return 1; 
} 
} 
static void Main(string[] args) 
{ 
Student[] students = new Student[]{ 
new Student(){Age = 10,Name=" zhang 3",Score=70}, 
new Student(){Age = 12,Name=" li 4",Score=97}, 
new Student(){Age = 11,Name=" The king 5",Score=80}, 
new Student(){Age = 9,Name=" zhao 6",Score=66}, 
new Student(){Age = 12,Name=" Si ma ",Score=90}, 
}; 
Console.WriteLine("-------------- Default sort output --------"); 
Array.Sort(students); 
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2} At the age of 18, his score is {2,3}", s.Name, s.Age, s.Score))); 
Console.WriteLine("---------- Sort the output by score ------------"); 
Array.Sort(students, new StudentScoreComparer()); 
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2} At the age of 18, his score is {2,3}", s.Name, s.Age, s.Score))); 
Console.WriteLine("---------- Sort the output by score ----------"); 
Array.Sort(students, (s1, s2) => s1.Score.CompareTo(s2.Score)); 
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2} At the age of 18, his score is {2,3}", s.Name, s.Age, s.Score))); 
Console.Read(); 
} 
public class StudentScoreComparer : IComparer<Student> 
{ 
public int Compare(Student x, Student y) 
{ 
return x.Score.CompareTo(y.Score); 
} 
} 
} 
} 

Conclusion:
There are three interfaces for comparing object sizes in C#, IComparable and IComparable < T > And IComparer < T > . IComparable and IComparable < T > Is the behavior definition implemented by the class itself to compare sizes between instances. IComparer < T > Defines the behavior of specifically comparing the size of two objects of type T outside of the class being compared, and one delegate for comparison defines Comparison < T > We can use ramda expressions or anonymous delegates or methods to sort more easily.

Related articles: