Изменить сортировку в C # - PullRequest
4 голосов
/ 03 июня 2010

Допустим, у меня есть строки abc_ и abc2_. Теперь, обычно при сортировке я C # abc2_ следовал бы после abc_, оставляя результат:

  1. abc_
  2. abc2_

Я использую это для сортировки, если это имеет значение:

     var element = from c in elements
     orderby c.elementName ascending
     select c;

Как я могу это изменить? Я хочу, чтобы abc_ был последним. Реверсировать нельзя, поскольку список содержит более двух элементов.

Ответы [ 5 ]

4 голосов
/ 05 июня 2010

Самое простое решение - использовать встроенный в .NET Framework метод сравнения строк:

var element = from c in elements
    .OrderBy(c => c.elementName, StringComparer.Ordinal) 
    select c; 

Не требуется пользовательский класс Comparer!

4 голосов
/ 03 июня 2010

Метод OrderBy потенциально может принимать аргумент IComparer<T>. (Я не уверен, что эту перегрузку можно использовать с синтаксисом понимания запросов или он доступен только при использовании синтаксиса свободно распространяемого метода расширения.)

Поскольку не совсем ясно, что именно должен включать в себя ваш алгоритм сортировки, я оставлю реализацию требуемого IComparer<T> в качестве упражнения для читателя.

1 голос
/ 03 июня 2010

Если вы хотите подчеркнуть, что не играете никакой роли в сравнении, мы можем просто сделать это.Итак:

class CustomComparer : Comparer<string>
    {            
        public override int Compare(string a, string b)
        {   
            //Jamiec fixed the line below.             
            return a.Replace("_", "").CompareTo(b.Replace("_", ""));
        }
    }


var customComparer = new CustomComparer();                                    
var element = elements.OrderBy(c => c.elementName, customComparer);
0 голосов
/ 04 июня 2010

Использование CompareOptions.Ordinal добился цели.

0 голосов
/ 03 июня 2010

Я до сих пор не уверен в том, какой именно шаблон мы пытаемся отсортировать, но я написал то, что, по моему мнению, было бы решением. Я видел «_» как своего рода подстановочный знак, где «abc2_» будет подмножеством «abc_». Но из комментариев ОП "bar_" <"barxyz" нарушает мое понимание. Вот мой код, и я могу изменить его, когда получу больше ясности. </p>

static void Main(string[] args)
    {
        List<Element> Elements = new List<Element>();
        Elements.Add(new Element("abc_"));
        Elements.Add(new Element("abc2_"));
        Elements.Add(new Element("aaa"));

        var max = Elements.Max(e => e.Name.Length);
        var result = Elements.OrderBy(e => e.Name, new CustomComparer(max));

        foreach (var item in result)
            Console.WriteLine(item.Name);

        Console.Read();

    }

    class Element
    {
        public string Name { get; private set; }
        public Element(string name)
        {
            this.Name = name;
        }
    }

    class CustomComparer : Comparer<string>
    {
        private const string cWildCard = "_";
        private const char cHeavyChar = 'Z';
        public int Max { get; private set; }
        public CustomComparer(int max)
        {
            this.Max = max;
        }
        public override int Compare(string a, string b)
        {
            string comp1 = string.Empty, comp2 = string.Empty;

            int index = a.IndexOf(cWildCard);
            if (index > 0)
                comp1 = a.Substring(0, index).PadRight(this.Max, cHeavyChar);
            index = b.IndexOf(cWildCard);
            if (index > 0)
                comp2 = b.Substring(0, index).PadRight(this.Max, cHeavyChar);

            int result = comp1.CompareTo(comp2);
            return result;
        }
    }

Вы можете видеть, что я просто взвешиваю слово, более тяжелое от того, где находится "_". Дайте мне знать, если это на правильном пути.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...