#c# #string #enums #compare
Вопрос:
У меня есть перечисление, в котором элементы упорядочены по смыслу:
enum MyEnum
{
LORRY,
BIKE,
AMBULANCE,
CAR
};
Затем у меня есть некоторые строки, такие как:
"1 CAR AND A LORRY"
"1 LORRY AND A BIKE"
"1 AMBULANCE AND A BIKE"
"1 LORRY AND A AMBULANCE"
Сортировка этих строк в алфавитном порядке приведет к:
"1 AMBULANCE AND A BIKE"
"1 CAR AND A LORRY"
"1 LORRY AND A AMBULANCE"
"1 LORRY AND A BIKE"
Но я хочу отсортировать строки в соответствии с порядком моего перечисления. Так что мой результат должен быть:
"1 LORRY AND A BIKE"
"1 LORRY AND A AMBULANCE"
"1 AMBULANCE AND A BIKE"
"1 CAR AND A LORRY"
Я решил, что могу заменить каждое появление значений перечисления в строках индексом перечисления и использовать новые строки в строке.Сравните() для достижения правильного порядка. Проблема в том, как заменить строки индексами для достижения:
"1 0 AND A 1"
"1 0 AND A 2"
"1 2 AND A 1"
"1 3 AND A 0"
т.е.
public int Compare(object x, object y)
{
TreeNode tx = x as TreeNode;
TreeNode ty = y as TreeNode;
string s1 = tx.Text;
string s2 = tx.Text;
// What Goes here to replace the enum values in the strings with the enum index?
// I tried this but the replace seems not to work
MyEnum[] myEnums= Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().ToArray();
for (int i = positions.Length - 1; i >= 0; i--)
{
MyEnum myEnum = myEnums[i];
string str = myEnum.ToString();
string index = ((int)myEnum).ToString();
s1.Replace(str, index);
s2.Replace(str, index);
}
return string.Compare(s1, s2);
}
Комментарии:
1. Вы смотрели на
string.Replace()
иenum.ToString()
иstring.Contains()
???2. Я пытался, но не могу заставить его работать, отсюда и просьба о помощи. См. Обновление выше. Спасибо
3. Посмотрите еще раз;
Replace()
возвращает новую строку, она не изменяет вызывающую строку.4. Я чувствую себя глупо. Спасибо
Ответ №1:
Что-то, над чем ты можешь поработать:
- Получите список имен участников Перечислителя в виде строки
- Упорядочьте массив строк на основе значений, определяемых содержимым списка имен
- Учитывайте только слова, соответствующие члену перечислителя
- Придайте больше значения слову в зависимости от его положения внутри строки: при нахождении в первой позиции слово имеет максимальное значение; значение постепенно уменьшается для каждой позиции после первой. Формула просто:
double value = [position] * (int.MaxValue / Math.Exp([Index] * 2))
используйте любое другое выражение, значение которого уменьшается при увеличении оцениваемой позиции. У этого есть ограничение ~350 позиций в каждой отдельной строке; после этого Math.Exp()
возвращается 0
.
Эта форма явно имеет ограничение: строки, которые не содержат слов, соответствующих имени члена перечислителя, перечислены первыми, но никак не упорядочены. Это не входило в вопрос. Измените по мере необходимости.
string[] phrases = new[] {
"1 LORRY AND A BIKE",
"1 AMBULANCE AND AN BIKE FOLLOW BY A LORRY",
"1 LORRY AND AN AMBULANCE",
"1 CAR AND A BIKE",
"1 AMBULANCE AND A BIKE",
"1 LORRY AND A LORRY",
"1 NO CARS OR BIKES",
"1 AMBULANCE AND A BLUE CAR AND A RED CAR AND A WHITE CAR",
"1 CAR AND ANOTHER FANCY LORRY"
};
var enumNames = Enum.GetNames(typeof(StringyEnum)).ToList();
var ordered = phrases.OrderBy(sv => sv.Split().Where(enumNames.Contains)
.Select((s, i) => (s, i)).Sum(n =>
(enumNames.IndexOf(n.s) 1) * (int.MaxValue / Math.Exp(n.i*2))
));
Это упорядочивает строку следующим образом:
1 NO CARS OR BIKES
1 LORRY AND A LORRY
1 LORRY AND A BIKE
1 LORRY AND AN AMBULANCE
1 AMBULANCE AND A BIKE
1 AMBULANCE AND AN BIKE FOLLOW BY A LORRY
1 AMBULANCE AND A BLUE CAR AND A RED CAR AND A WHITE CAR
1 CAR AND ANOTHER FANCY LORRY
1 CAR AND A BIKE