Я использовал следующий подход в проекте некоторое время назад. Это не особенно эффективно, но если количество сортируемых элементов невелико, оно достаточно хорошо для этого использования. Что он делает, так это то, что он разбивает строки для сравнения на массивы символа '_'
, а затем сравнивает каждый элемент массивов. Предпринята попытка проанализировать последний элемент как int и провести там числовое сравнение.
Он также имеет ранний выход, если входные строки будут содержать различное количество элементов (поэтому, если вы сравните «file_nbr_1» с «file_23», он не будет сравнивать каждую часть строк, а скорее просто с обычное сравнение строк на полных строках):
char[] splitChars = new char[] { '_' };
string[] strings = new[] {
"file_1",
"file_8",
"file_11",
"file_2"
};
Array.Sort(strings, delegate(string x, string y)
{
// split the strings into arrays on each '_' character
string[] xValues = x.Split(splitChars);
string[] yValues = y.Split(splitChars);
// if the arrays are of different lengths, just
//make a regular string comparison on the full values
if (xValues.Length != yValues.Length)
{
return x.CompareTo(y);
}
// So, the arrays are of equal length, compare each element
for (int i = 0; i < xValues.Length; i++)
{
if (i == xValues.Length - 1)
{
// we are looking at the last element of the arrays
// first, try to parse the values as ints
int xInt = 0;
int yInt = 0;
if (int.TryParse(xValues[i], out xInt)
&& int.TryParse(yValues[i], out yInt))
{
// if parsing the values as ints was successful
// for both values, make a numeric comparison
// and return the result
return xInt.CompareTo(yInt);
}
}
if (string.Compare(xValues[i], yValues[i],
StringComparison.InvariantCultureIgnoreCase) != 0)
{
break;
}
}
return x.CompareTo(y);
});