0

I have a list similar to this:

List<Item> myList = new List<myObj>();
myList.Add(new Item({ val = A1, text="A1 - Alpha1"});
myList.Add(new Item({ val = A2, text="A2 - Alpha2"});
myList.Add(new Item({ val = A10, text="A10 - Alpha10"});
myList.Add(new Item({ val = A, text="A - Alpha"});

I'm looking to order this list alphabetically by their values so:

"A", "A1", "A2", "A10"

would be the desired order but I end up getting:

"A", "A1", "A10", "A2"

when using Linq's .OrderBy(x=>x.val) method.

I have tried some answers on Stack Overflow using custom ordering but these answers don't account for a mixture of values where it may or may not contain a numeric entry. Some of these orders are involving conversions to ints which won't satisfy all the values in my list.

How would it be possible to obtain the correct ordered result?

NiallMitch14
  • 1,198
  • 1
  • 12
  • 28
  • Can you show an example of values where converting to int wouldn't work? (disclaimer: I have a naively written nuget package called lvk.naturally that could probably help you but not without knowing more about what kind of special handling you would require). Also, please try to form a [mcve] when posting, makes it easier for us to help you (as in, it should compile and be complete but minimal) – Lasse V. Karlsen May 21 '21 at 14:06
  • 1
    This is called "natural sort order", see e.g. here: https://stackoverflow.com/questions/248603/natural-sort-order-in-c-sharp – Klaus Gütter May 21 '21 at 14:12
  • There's an overload of `IEnumerable.OrderBy` that takes an `IComparer`. Write a comparer that suits your needs. As the link provided by @KlausGütter points out, make sure that it meets the specifications of a comparer (if A==B and B==C, then A==C, if A – Flydog57 May 21 '21 at 14:12
  • Thanks @KlausGütter you pointed me in the right direction! Got it working using Matthews Horsleys solution! – NiallMitch14 May 21 '21 at 14:46

2 Answers2

0

Please try below code

.OrderBy(x => Regex.Match(x.val, @"\d+").Value == "" ? 0 : Convert.ToInt32(Regex.Match(x.val, @"\d+").Value)).ThenBy(x => Regex.Match(x.val, @"[^A-Z]+").Value)
0

Thanks to @KlausGütter I was pointed in the right direction to solve this! I used Matthey Horsleys answer from this thread:

https://stackoverflow.com/a/11720793/4611941

as an extension method for IEnumerables and was able to simply call this method, passing in the parameter to sort by and it handled it perfectly!

i.e. after implementing the extension, I called

myList.OrderByAlphaNumeric(x=> x.val);

and it sorts correctly.

NiallMitch14
  • 1,198
  • 1
  • 12
  • 28