У меня сложный шаблон сортировки для репликации, и моё решение кажется несколько затрудненным.Мои данные представляют собой список чисел, которые могут содержать несколько букв в качестве суффикса, а префикс - только буквы («aaa», «aab», «ac» и т. Д.).Мне нужно отсортировать численно, затем отсортировать по суффиксу (если он есть), а затем по префиксу (если он есть).
Например,
"a1a",
"5ac",
"1",
"12",
"2",
"11",
"5aa",
"3",
"5ab",
"a2b",
"abb11ca",
"1b",
"aba11ca"
будет отсортировано как
1
a1a
1b
2
a2b
3
5aa
5ab
5ac
11
aba11ca
abb11ca
12
Вот решение, которое я придумал, используя Linq.
static void Main(string[] args)
{
var arr = new []
{"b2","a1a","5ac","1","12","2","11","5aa","3","5ab","a1","a2b","abb11ca","1b","aba11ca"
};
var ordered = arr.Select(str => {
var parts = SplitIntoPrefixNumberSuffix(str);
var number = int.Parse(parts[1]);
return new { str, parts, number };
})
.OrderBy(x => x.number).ThenBy(x => x.parts[2]).ThenBy(x => x.parts[0])
.Select(x => x.str);
Console.WriteLine("sorted array: ");
foreach (var s in ordered)
{
Console.WriteLine("{0}", s);
}
Console.ReadLine();
}
public static string[] SplitIntoPrefixNumberSuffix(string str)
{
var numChar = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
var numLoc = str.IndexOfAny(numChar);
var nums = "";
foreach (var c in str)
{
if (char.IsDigit(c))
nums = nums + c;
}
Console.WriteLine("numLoc: {0}; nums: {1}", numLoc, nums.Count());
var prefix = str.Substring(0, numLoc);
var suffix = str.Substring(numLoc + nums.Count());
Console.WriteLine("prefix {0}; nums {1}; suffix {2}", prefix, nums, suffix);
return new[] { prefix, nums, suffix };
}
Вот .netfiddle из него работает: https://dotnetfiddle.net/C7ZA0b.
Пока оно работает, оноТакое ощущение, что это не очень хорошее решение.Я перебираю коллекцию несколько раз, и я думаю, что я должен использовать пользовательский сопоставимый.
Я никогда раньше не писал Comparable;Я посмотрел на Алфавитно-цифровая сортировка Dot Net Pearls и могу следить за ним, но недостаточно хорошо, чтобы изменить его в соответствии со своими потребностями.
Есть ли какой-нибудь IComparable, который я могу использовать для выполнения вышеуказанной работы?Любые предложения о хорошем месте, чтобы узнать, как написать один?