Adolfo Perez Adolfo Perez - 2 months ago 15
C# Question

List Custom Sort

I have a list of items which need to be sorted in a very particular way.

Take this example:

public class PayStubDetailItem
{
public string Code { get; set; }
}

void Main()
{
var bonus = new PayStubDetailItem() { Code = "Bonus" };
var ot = new PayStubDetailItem() { Code = "OT"};
var reg = new PayStubDetailItem() { Code = "Reg"};
var otPrem = new PayStubDetailItem() { Code = "OTPrem"};
var tps = new PayStubDetailItem() { Code = "3ps"};

var list = new List<PayStubDetailItem> {
bonus, ot, reg, otPrem, tps
};
}


My requirement states that sorting should be as follows:
Reg, OT, OTPrem, Alpha-sort by code.

Explained in words, if list contains 'Reg' code it should come first, if it also contains 'OT' it should come after Reg, etc.. All items which codes are different from those specific three should be alphabetically sorted.

In my example the sorted list should look like this:
Reg, OT, OTPrem, 3ps, Bonus

What would be the most elegant way to accomplish that? Perhaps, using LINQ or a custom comparer.

This is what I have attempted so far but it's to verbose:

var subList = list.Where(i => i.Code != "OT" && i.Code != "Reg" && i.Code != "OTPrem");
subList = subList.OrderBy(l => l.Code);
var newList = new List<PayStubDetailItem>();
if (list.Select(c => c.Code).Contains("Reg"))
{
newList.Add(list.Where(i => i.Code == "Reg").FirstOrDefault());
}
if (list.Select(c => c.Code).Contains("OT"))
{
newList.Add(list.Where(i => i.Code == "OT").FirstOrDefault());
}
if (list.Select(c => c.Code).Contains("OTPrem"))
{
newList.Add(list.Where(i => i.Code == "OTPrem").FirstOrDefault());
}
newList.AddRange(subList);
newList.Dump();


Thanks

Answer

You can use Linq like this:

var result = list.
    .OrderBy(c => c.Code == "Reg" ? 0 : c.Code == "OT" ? 1 : c.Code == "OTPrem" ? 2 : 3)
    .ThenBy(c => c.Code)
    .ToList();

The OrderBy expression will give you the required priority order, while the ThenBy will do the alphabetical part.

Comments