There is an array of rows
list & lt; string & gt; S = New List & LT; String & GT; {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11 "," 12 "," 13 "," 14 "," 15c "," 15b "," 150 "," 15a "};
If we just call
s.sort ();
then he sorts them as
1
ten
eleven
12
13
fourteen
150.
15A
15b.
15C.
2.
3.
4
5
6.
7.
eight
9
How to make it gives out intuitively human sorting? Those. Working and sorting on String, but first of all – also by the value of the number. Those. The correct output in this case will be
1,2,3,4,5,6,7,8,9,10,11,12,13,15A, 15B, 15C, 150;
I understand that you can write a comparator, which probably searches for numbers inside the line if it finds them, checks where more, and if the line is alphabetically, but how exactly implement?
And then rather a question, maybe something like that has already been implemented? Maybe there is some kind of stringcomparsion.numericfirst, which is simply transmitted to the argument into sorting and sorts as a person sorted?
Answer 1, Authority 100%
Here is my attempt. I do not pretend to genius, because myself is weak in regular, it is probably a way simpler.
Public Static Void Main ()
{
List & lt; String & GT; S = New List & LT; String & GT; {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", " 13 "," 14 "," 15c "," 15b "," 150 "," 15a "};
S.SORT (New MyComparr ());
Console.WriteLine (String.join (",", s));
Console.ReadKey ();
}
Public Class Mycomparer: ICOMPARER & LT; String & GT;
{
Private Readonly Regex Regex = New Regex (@ "(\ D +) ([A-Z]?)");
Public Int Compare (String X, String Y)
{
Match M1 = REGEX.Match (X);
Match M2 = REGEX.Match (Y);
int a = int.parse (M1.Groups [1] .Value);
int b = int.parse (m2.groups [1] .Value);
IF (A & LT; B)
Return -1;
if (a & gt; b)
Return 1;
Return String.comPare (M1.Groups [2] .Value, M2.Groups [2] .Value);
}
}
Again, there is no protective programming here if you use this option, take care of cases where the string has an incorrect format.
Conclusion in the console
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15A, 15B, 15C, 150.
Option without int.parse
.
Public Class MyComparr: ICOMPARER & LT; String & GT;
{
Private Readonly Regex Regex = New Regex (@ "(\ D +) ([A-Z]?)");
Public Int Compare (String X, String Y)
{
Match M1 = REGEX.Match (X);
Match M2 = REGEX.Match (Y);
String num1 = m1.groups [1] .Value;
String num2 = m2.groups [1] .Value;
if (num1.length & lt; num2.length)
Return -1;
if (num1.length & gt; num2.length)
Return 1;
int cmp = string.compare (num1, num2);
if (CMP! = 0)
Return CMP;
Return String.comPare (M1.Groups [2] .Value, M2.Groups [2] .Value);
}
}