TheJackal
TheJackal

Reputation: 435

Custom sorting using LINQ and Function

I have a list of strings each of which are exactly 2 characters long. I wish to sort it. I begin by sorting the list by the first character of each string using

.OrderBy(e => e[0])

but my problem is when sorting the second character, something like:

.ThenBy(string1 => string1, string2 => string2 Compare(string1,string2)

I want to select two strings and pass them to the function I created called compare.

Can someone tell me how I would do this or if there is a better way of doing what I want? Please share.

public string sortT(string h)
{
    var sortedList = l
                    .OrderBy(e => e[0])
                    .ThenBy()
                    .ToList<string>();
    return sb.ToString();
}
private int Compare(string a, string b)
{
    List<char> value = new List<char>() {
        '2', '3', '4', '5', '6', '7', '8', '9','J','Q', 'K', 'A' };           
    if (value.IndexOf(a[1]) > value.IndexOf(b[1]))
        return 1; 
    return -1;
}

Upvotes: 1

Views: 1906

Answers (1)

Tim Schmelter
Tim Schmelter

Reputation: 460238

You can use your list as basis:

List<char> value = new List<char>() { '2', '3', '4', '5', '6', '7', '8', '9','J','Q', 'K', 'A' };

var sortedList = l.OrderBy(str => str[0])
                  .ThenBy(str => value.IndexOf(str[1]))
                  .ToList<string>();

You could also implement a custom IComparer<T> like this:

public class TwoCharComparer : IComparer<string>
{
    private static readonly List<char> value = new List<char>() { '2', '3', '4', '5', '6', '7', '8', '9', 'J', 'Q', 'K', 'A' };

    public int Compare(string x, string y)
    {
        if (x == null || y == null || x.Length < 2 || y.Length < 2) return 0; // ignore
        int comparison = x[0].CompareTo(y[0]);
        if (comparison != 0)
            return comparison;
        int ix1 = value.IndexOf(x[1]);
        int ix2 = value.IndexOf(y[1]);
        if(ix1 == ix2 && ix1 == -1)
            return x[1].CompareTo(y[1]);  
        else
            return ix1.CompareTo(ix2);
    }
}

Now you can pass that to List.Sort which does not need to create a new list:

var l = new List<string> { "C1", "B2", "A2", "B1", "A1", "C3", "C2" };
l.Sort(new TwoCharComparer()); // A1,A2,B1,B2,C1,C2,C3

Upvotes: 5

Related Questions