Sort a list of objects in C#
This post will discuss how to sort a list of objects using some property in C#.
C# has a built-in Sort() method that performs in-place sorting to sort a list of objects. The sorting can be done using a Comparison<T>
delegate or an IComparer<T>
implementation.
1. Using Comparison<T>
Delegate
A comparison delegate is used to provide order on objects that don’t have a natural ordering. If passed to a sort method, it allows precise control over the sort order of elements. We can implement the comparison delegate via anonymous methods, which allow code blocks to be passed as parameters instead of a separate method.
The following example sorts a list of Employee
objects by their age using the specified Comparison<T>
delegate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using System; using System.Linq; using System.Collections.Generic; public class Employee { public string name; public int age; public Employee(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Employee john = new Employee("John", 24); Employee sam = new Employee("Sam", 27); Employee roger = new Employee("Roger", 21); List<Employee> employees = new List<Employee>() { john, sam, roger }; employees.Sort(delegate(Employee x, Employee y) { return x.age.CompareTo(y.age); }); Console.WriteLine(String.Join(Environment.NewLine, employees)); } } /* Output: [Roger,21] [John,24] [Sam,27] */ |
Lambda expressions offer a more concise way of writing inline code blocks in C#. To compare the List of Employee
objects by their age, we can do:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
using System; using System.Collections.Generic; public class Employee { public string name; public int age; public Employee(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Employee john = new Employee("John", 24); Employee sam = new Employee("Sam", 27); Employee roger = new Employee("Roger", 21); List<Employee> employees = new List<Employee>() { john, sam, roger }; employees.Sort((x, y) => x.age.CompareTo(y.age)); Console.WriteLine(String.Join(Environment.NewLine, employees)); } } /* Output: [Roger,21] [John,24] [Sam,27] */ |
2. Implement IComparer<T>
Another approach is to provide a custom IComparer<T> implementation for sorting a list using the Sort()
method. The idea is to implement the IComparer<T>
interface in a separate class and pass that class’s instance to the Sort()
method.
The implementing class needs to override the Compare()
method, which takes two objects. The value returned by the Compare()
method decides the relative order of the first object with respect to the second object in the sorted list. A negative, zero, and a positive value representing the first object is less than, equal to, or greater than the second object. This is demonstrated below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
using System; using System.Collections.Generic; public class EmployeeComparer: IComparer<Employee> { public int Compare(Employee x, Employee y) { if (object.ReferenceEquals(x, y)) { return 0; } if (x == null) { return -1; } if (y == null) { return 1; } return x.age.CompareTo(y.age); } } public class Employee { public string name; public int age; public Employee(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Employee john = new Employee("John", 24); Employee sam = new Employee("Sam", 27); Employee roger = new Employee("Roger", 21); List<Employee> employees = new List<Employee>() { john, sam, roger }; employees.Sort(new EmployeeComparer()); Console.WriteLine(String.Join(Environment.NewLine, employees)); } } /* Output: [Roger,21] [John,24] [Sam,27] */ |
3. Implement IComparable<T>
The IComparable<T> Interface imposes a natural ordering on the objects of each class that implements it. The implementing class needs to override the CompareTo()
method, which compares the current object with the specified object. The value returned by the compareTo()
method decides the relative order of the objects in the sorted list. A negative, zero, and a positive value representing the object is less than, equal to, or more than the specified object.
In the following code, the Employee
class implements the IComparable<T>
interface and override its CompareTo()
method. The List
of Employee
objects is then sorted using the no-arg Sort()
method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
using System; using System.Collections.Generic; public class Employee: IComparable<Employee> { public string name; public int age; public Employee(string name, int age) { this.name = name; this.age = age; } public int CompareTo(Employee emp) { if (emp == null) { return 1; } return Comparer<int>.Default.Compare(this.age, emp.age); } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Employee john = new Employee("John", 24); Employee sam = new Employee("Sam", 27); Employee roger = new Employee("Roger", 21); List<Employee> employees = new List<Employee>() { john, sam, roger }; employees.Sort(); Console.WriteLine(String.Join(Environment.NewLine, employees)); } } /* Output: [Roger,21] [John,24] [Sam,27] */ |
4. Using LINQ OrderBy()
method
The List Sort()
method sorts the list in-place. To create a new sorted copy of the list, we can use LINQ’s OrderBy() method. This creates a new list with the elements of the original list sorted according to a key. The following code example demonstrates its usage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using System; using System.Linq; using System.Collections.Generic; public class Employee { public string name; public int age; public Employee(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Employee john = new Employee("John", 24); Employee sam = new Employee("Sam", 27); Employee roger = new Employee("Roger", 21); List<Employee> employees = new List<Employee>() { john, sam, roger }; List<Employee> sorted = employees.OrderBy(x => x.age).ToList(); Console.WriteLine(String.Join(Environment.NewLine, sorted)); } } /* Output: [Roger,21] [John,24] [Sam,27] */ |
Using LINQ Query Expressions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using System; using System.Linq; using System.Collections.Generic; public class Employee { public string name; public int age; public Employee(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Employee john = new Employee("John", 24); Employee sam = new Employee("Sam", 27); Employee roger = new Employee("Roger", 21); List<Employee> employees = new List<Employee>() { john, sam, roger }; List<Employee> sorted = (from e in employees orderby e.age select e).ToList(); Console.WriteLine(String.Join(Environment.NewLine, sorted)); } } /* Output: [Roger,21] [John,24] [Sam,27] */ |
That’s all about sorting a list of objects in C#.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)