Замените вхождения значений перечисления в строке индексом значения перечисления для сравнения строк

#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