c#: Sorting List of Complex Type or an Object using IComparable

To do sorting with List<T> of your own object type you need to implement IComparable<T> interface into the class itself. So when you have a List of the object you can easily call listOfObject.Sort() to sort the content of that list.
For example: imagine you have a Class Schedule for work schedule and that class have 2 properties which is  WorkDay and Shift. Both properties are a complex type or i should say a struct of itself and each of those have their own members and properties. Now if you’re going to sort a list of Schedule (List) and you have sort it based on the value of  it’s properties, for this example we want to sort it based on WorkDay and Shift. To be able to do that we need to implement IComparable<T> interface on each of the members of Schedule object and the Schedule object itself.

According to documentation the IComparable<T> interface defines generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering or sorting its instances.

WorkDay class has two properties; Day int dan DayName string. Day is an integer that will be use to do comparison and DayName is the name of the day in string.WorkDay class needs to implement IComparable<T> interface where T is WorkDay and implement CompareTo method. The method CompareTo must return an Int32 with three possible values such as:

  • lest than zero, when the current object precedes the object specified by the CompareTo method in the sort order.
  • zero, the current instance occurs in the same position in the sort order as the object specified by the CompareTo method argument.
  • more than zero, the current instance follows the object specified by the CompareTo method argument in the sort order.

In this example we’re going to compare the Day property which of type int, with simple if else and logical operators would do the trick to figure out whether current instance of the object precedes or follows the object in the CompareTo method argument. Same principle also applies to Shift object, as for the Schedule object we simply call each property CompareTo methods inside Schedule.CompareTo and returns the result.

icomparable result
work schedule icomparable

Here’s the source code on gist and a github repo for this tutorial.

class Program
{
private static WorkDay workday1 = new WorkDay { Day = 1, DayName = "Monday" };
private static WorkDay workday2 = new WorkDay { Day = 2, DayName = "Tuesday" };
private static WorkDay workday3 = new WorkDay { Day = 3, DayName = "Wednesday" };
private static WorkDay workday4 = new WorkDay { Day = 4, DayName = "Thursday" };
private static WorkDay workday5 = new WorkDay { Day = 5, DayName = "Friday" };
private static Shift shift1 = new Shift { Start = TimeSpan.Parse("08:00"), End = TimeSpan.Parse("12:00"), Name = "Shift 1" };
private static Shift shift2 = new Shift { Start = TimeSpan.Parse("12:00"), End = TimeSpan.Parse("16:00"), Name = "Shift 2" };
private static Shift shift3 = new Shift { Start = TimeSpan.Parse("16:00"), End = TimeSpan.Parse("20:00"), Name = "Shift 3" };
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
List<Schedule> list = new List<Schedule>
{
new Schedule
{
Shift = shift1,
WorkDay= workday1
},
new Schedule
{
Shift = shift2,
WorkDay= workday4
},
new Schedule
{
Shift = shift1,
WorkDay= workday2
},
new Schedule
{
Shift = shift2,
WorkDay= workday1
},
new Schedule
{
Shift = shift1,
WorkDay= workday5
},
new Schedule
{
Shift = shift2,
WorkDay= workday3
},
};
Console.WriteLine("Before Sorting");
foreach (var item in list)
{
Console.WriteLine($"{item.WorkDay.DayName} – on {item.Shift.Name} from {item.Shift.Start} to {item.Shift.End}.");
}
Console.WriteLine("\n\n\n\n");
list.Sort();
Console.WriteLine("After Sorting");
foreach (var item in list)
{
Console.WriteLine($"{item.WorkDay.DayName} – on {item.Shift.Name} from {item.Shift.Start} to {item.Shift.End}.");
}
Console.ReadKey();
}
}

view raw
Program.cs
hosted with ❤ by GitHub

class Schedule : IComparable<Schedule>
{
public int CompareTo(Schedule other)
{
int result = 0;
result += WorkDay.CompareTo(other.WorkDay);
result += Shift.CompareTo(other.Shift);
return result;
}
public WorkDay WorkDay { get; set; }
public Shift Shift { get; set; }
}

view raw
Schedule.cs
hosted with ❤ by GitHub

public struct Shift : IComparable<Shift>
{
public string Name { get; set; }
public TimeSpan Start { get; set; }
public TimeSpan End { get; set; }
public int CompareTo(Shift other)
{
if (Start > other.Start)
return 1;
else if(Start< other.Start)
return 1;
return 0;
}
}

view raw
Shift.cs
hosted with ❤ by GitHub

public struct WorkDay : IComparable<WorkDay>
{
public int Day { get; set; }
public string DayName { get; set; }
public int CompareTo(WorkDay other)
{
if (Day > other.Day)
return 2;
else if(Day<other.Day)
return 2;
return 0;
}
}

view raw
WorkDay.cs
hosted with ❤ by GitHub

Published by Gadael Sedubun

Developer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: