Tar*_*zan 10 .net c# sorting string numbers
我有一个字符串,其中包含以句点分隔的数字.当我排序时它看起来像这样,因为它是一个字符串:(ascii char order)
3.9.5.2.1.1
3.9.5.2.1.10
3.9.5.2.1.11
3.9.5.2.1.12
3.9.5.2.1.2
3.9.5.2.1.3
3.9.5.2.1.4
Run Code Online (Sandbox Code Playgroud)
等等
我希望它像这样排序:(按数字顺序)
3.9.5.2.1.1
3.9.5.2.1.2
3.9.5.2.1.3
...
3.9.5.2.1.9
3.9.5.2.1.10
3.9.5.2.1.11
3.9.5.2.1.12
Run Code Online (Sandbox Code Playgroud)
我知道我可以:
如果重复现有功能,我宁愿避免所有这些工作..net框架中的方法是否已经执行此操作?
这是我的工作解决方案,它也处理格式不正确的字符串(例如包含文本)。
这个想法是获取两个字符串中的第一个数字并比较这些数字。如果它们匹配,则继续下一个数字。如果他们不这样做,我们就有一个赢家。如果这些数字根本不是数字,则对尚未比较的部分进行字符串比较。
通过改变确定下一个数字的方式,可以很容易地使比较器完全兼容自然排序顺序。
看那个..刚发现这个问题。
比较器:
class StringNumberComparer : IComparer<string>
{
public int Compare(string x, string y)
{
int compareResult;
int xIndex = 0, yIndex = 0;
int xIndexLast = 0, yIndexLast = 0;
int xNumber, yNumber;
int xLength = x.Length;
int yLength = y.Length;
do
{
bool xHasNextNumber = TryGetNextNumber(x, ref xIndex, out xNumber);
bool yHasNextNumber = TryGetNextNumber(y, ref yIndex, out yNumber);
if (!(xHasNextNumber && yHasNextNumber))
{
// At least one the strings has either no more number or contains non-numeric chars
// In this case do a string comparison of that last part
return x.Substring(xIndexLast).CompareTo(y.Substring(yIndexLast));
}
xIndexLast = xIndex;
yIndexLast = yIndex;
compareResult = xNumber.CompareTo(yNumber);
}
while (compareResult == 0
&& xIndex < xLength
&& yIndex < yLength);
return compareResult;
}
private bool TryGetNextNumber(string text, ref int startIndex, out int number)
{
number = 0;
int pos = text.IndexOf('.', startIndex);
if (pos < 0) pos = text.Length;
if (!int.TryParse(text.Substring(startIndex, pos - startIndex), out number))
return false;
startIndex = pos + 1;
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
public static void Main()
{
var comparer = new StringNumberComparer();
List<string> testStrings = new List<string>{
"3.9.5.2.1.1",
"3.9.5.2.1.10",
"3.9.5.2.1.11",
"3.9.test2",
"3.9.test",
"3.9.5.2.1.12",
"3.9.5.2.1.2",
"blabla",
"....",
"3.9.5.2.1.3",
"3.9.5.2.1.4"};
testStrings.Sort(comparer);
DumpArray(testStrings);
Console.Read();
}
private static void DumpArray(List<string> values)
{
foreach (string value in values)
{
Console.WriteLine(value);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
....
3.9.5.2.1.1
3.9.5.2.1.2
3.9.5.2.1.3
3.9.5.2.1.4
3.9.5.2.1.10
3.9.5.2.1.11
3.9.5.2.1.12
3.9.test
3.9.test2
blabla
Run Code Online (Sandbox Code Playgroud)