Adolfo Perez
Adolfo Perez

Reputation: 2874

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

Upvotes: 1

Views: 57

Answers (2)

Ivan Stoev
Ivan Stoev

Reputation: 205539

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.

Upvotes: 1

Scott Perham
Scott Perham

Reputation: 2470

As your sorting logic is quite unique to your problem, I would suggest an implementation the IComparer(T) interface and then calling Sort(IComparer(T)) on your list.

class MyComparer : IComparer<PayStubDetailItem>
{
    public int Compare(PayStubDetailItem x, PayStubDetailItem y)
    {
        //Your implementation
    }
}

Upvotes: 0

Related Questions