I'm trying to sort an array of numbers that are strings and I'd like them to sort numerically.
The catch is that I cannot convert the numbers into int.
Here is the code:
string[] things= new string[] { "105", "101", "102", "103", "90" }; foreach (var thing in things.OrderBy(x => x)) { Console.WriteLine(thing); }
Output:
101, 102, 103, 105, 90
I'd like:
90, 101, 102, 103, 105
EDIT: The output can't be 090, 101, 102...
Updated the code sample to say "things
" instead of "sizes
". The array can be something like this:
string[] things= new string[] { "paul", "bob", "lauren", "007", "90" };
That means it needs to be sorted alphabetically and by number:
007, 90, bob, lauren, paul
Numeric sort (' sort -n ') treats the entire string as a single numeric value, and compares it to other values. For example, ' 8.1 ', ' 8.10 ' and ' 8.100 ' are numerically equivalent, and are ordered together. Similarly, ' 8.49 ' is numerically less than ' 8.5 ', and appears before first.
Pass a custom comparer into OrderBy. Enumerable.OrderBy will let you specify any comparer you like.
This is one way to do that:
void Main() { string[] things = new string[] { "paul", "bob", "lauren", "007", "90", "101"}; foreach (var thing in things.OrderBy(x => x, new SemiNumericComparer())) { Console.WriteLine(thing); } } public class SemiNumericComparer: IComparer<string> { /// <summary> /// Method to determine if a string is a number /// </summary> /// <param name="value">String to test</param> /// <returns>True if numeric</returns> public static bool IsNumeric(string value) { return int.TryParse(value, out _); } /// <inheritdoc /> public int Compare(string s1, string s2) { const int S1GreaterThanS2 = 1; const int S2GreaterThanS1 = -1; var IsNumeric1 = IsNumeric(s1); var IsNumeric2 = IsNumeric(s2); if (IsNumeric1 && IsNumeric2) { var i1 = Convert.ToInt32(s1); var i2 = Convert.ToInt32(s2); if (i1 > i2) { return S1GreaterThanS2; } if (i1 < i2) { return S2GreaterThanS1; } return 0; } if (IsNumeric1) { return S2GreaterThanS1; } if (IsNumeric2) { return S1GreaterThanS2; } return string.Compare(s1, s2, true, CultureInfo.InvariantCulture); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With