0

I have an asp dropdown list control, databound to a sql database. The values it receives look like this:

S1
S10
S10A
S10B
S10C
S1A
S1B
S1C
S1D

But i need it to sort by alpha first, then numeric but to include the last letter (if there is one). So the output should look like this:

S1
S1A
S1B
S1C
S1D
S10
S10A
S10B
S10C

I can do an ORDER BY in the select statement but that doesn't solve the problem.

Solomon Rutzky
  • 46,688
  • 9
  • 128
  • 171
Kieran Quinn
  • 1,085
  • 2
  • 22
  • 49
  • this is complicate, its a custom sort, but not so easy, place them on a list and make your sort using your custom complicate function.... – Aristos Feb 02 '15 at 13:12
  • 1
    Maybe you can help this post [Sorting of list contained strings having alphabetic/numeric](http://stackoverflow.com/questions/11896158/sorting-of-list-contained-strings-having-alphabetic-numeric) – androschuk.a Feb 02 '15 at 13:18
  • You can use a built-in Windows function to sort in a natural order, as I explain here: http://stackoverflow.com/a/19271974/106159 – Matthew Watson Feb 02 '15 at 13:23

1 Answers1

1

I haven't debugged and check it completely so it may contain some errors, But the general idea is to get all three sorting parameters out of the string in the collection:

  1. First letter - String sort.

  2. Number - Numberic sort.

  3. Last letter - String sort.

and then create an object that contains all three and sort accordingly.

    var items = new List<string> { "S1", "S10", "S10A", "S10B", "S10C", "S1A", "S1B", "S1C", "S1D" };

    var result = items.
        Select(o =>
        {
            var firstLetter = o[0];

            int lastLetterNumber;
            var lastChar = o[o.Length - 1].ToString();
            var lastLetterForSort = Int32.TryParse(lastChar, out lastLetterNumber) ? string.Empty : lastChar;

            var number = o.Substring(1,  lastLetterForSort.Equals(string.Empty) ? o.Length - 1 : o.Length - 2);

            return new { 
                FirstLetter = firstLetter  , 
                Number = Int32.Parse( number) , 
                LastLetter = lastLetterForSort , 
                Value = o
            };
        }).
        OrderBy(o => o.FirstLetter).
        ThenBy(o => o.Number).
        ThenBy(o => o.LastLetter).
        Select(o => o.Value).
        ToList();

hope it helps.

Y.S
  • 1,860
  • 3
  • 17
  • 30