#c# #list #sorting
#c# #Список #сортировка
Вопрос:
Мне нужно отсортировать List<string>
следующие 2 правила.
Мой string
элемент всегда будет отформатирован как XXXnnnnE
или XXXnnnnD
где X
прописные буквы от A до Z и n
цифры от 0 до 9.
Я хочу отсортировать свой список в алфавитном порядке, но я хочу E
, чтобы строка предшествовала D
строке, как показано ниже
DFG0001D
AWK0007E
ORK0127E
AWK0007D
DFG0001E
ORK0127D
необходимо отсортировать как
AWK0007E
AWK0007D
DFG0001E
DFG0001D
ORK0127E
ORK0127D
Как я мог этого добиться?
Спасибо за помощь
Ответ №1:
Вот фрагмент, как вы можете сделать это с помощью Linq OrderBy, а затем убывающих операций:
string[] arr = { "DFG0001D", "AWK0007E", "ORK0127E", "AWK0007D", "DFG0001E", "ORK0127D" };
arr = arr
.OrderBy(r => r.Substring(0, 7))
.ThenByDescending(s => s.Substring(7, 1))
.ToArray();
Ответ №2:
вы можете использовать пользовательский делегат и сравнить первые 3 символа и последний:
List<string> x = new List<string>();
x.Add("DFG0001D");
x.Add("AWK0007E");
x.Add("ORK0127E");
x.Add("AWK0007D");
x.Add("DFG0001E");
x.Add("ORK0127D");
x.Sort(delegate(string c1, string c2) {
string a = c1.Substring(0, 3) c1.Substring(c1.Length-1, 1);
string b = c2.Substring(0, 3) c2.Substring(c2.Length-1, 1);
return (a.CompareTo(b));
});
Console.WriteLine("After sort...");
foreach (string i in x)
{
Console.WriteLine(i);
}
Пример скрипки: https://dotnetfiddle.net/YAzvB4
Комментарии:
1. Отличное решение, но почему бы просто не создать делегат с лямбда-синтаксисом? Т.е.
(c1, c2) => {...}
2. После тестирования этот код, похоже, не работает. Элементы сортируются только по алфавиту.
After sort... AWK0007D AWK0007E DFG0001D DFG0001E ORK0127D ORK0127E
Ответ №3:
var list = new List<string>{
"DFG0001D",
"AWK0007E",
"ORK0127E",
"AWK0007D",
"DFG0001E",
"ORK0127D"
};
list.Sort((str1, str2) => {
var eq = string.Compare(str1.Substring(0, str1.Length - 1), str2.Substring(0, str2.Length - 1));
if (eq == 0)
eq = string.Compare(str2[str2.Length - 1].ToString(), "E");
return eq;
});
foreach (var str in list)
Console.WriteLine(str);
Вывод:
AWK0007E
AWK0007D
DFG0001E
DFG0001D
ORK0127E
ORK0127D
Ответ №4:
просто реализуйте свой собственный компаратор следующим образом:
class CustomStringComparer : IComparer<string>
{
private readonly IComparer<string> _baseComparer;
public CustomStringComparer(IComparer<string> baseComparer)
{
_baseComparer = baseComparer;
}
public int Compare(string x, string y)
{
// strings are completely same
if (_baseComparer.Compare(x, y) == 0)
{
return 0;
}
// strings are completely same except last char
if (_baseComparer.Compare(x.Substring(0, x.Length - 2), y.Substring(0, y.Length - 2)) == 0)
{
// if last char is E then win
return x.Last() == 'E' ? -1 : 1;
}
// defaut compare everything else
return _baseComparer.Compare(x, y);
}
}
Тогда вы сможете это сделать:
static void Main(string[] args)
{
List<string> list = new List<string>()
{
"DFG0001D",
"AWK0007E",
"ORK0127E",
"AWK0007D",
"DFG0001E",
"ORK0127D"
};
list.Sort(new CustomStringComparer(StringComparer.CurrentCulture));
foreach (var item in list)
{
Console.WriteLine(item);
}
}
И вывод такой:
AWK0007E
AWK0007D
DFG0001E
DFG0001D
ORK0127E
ORK0127D