Упорядочение списка на месте по двум свойствам

У меня есть класс с двумя свойствами: Имя и Позиция. Я хотел бы упорядочить список с этим классом по позиции, а элементы с одинаковой позицией должны быть упорядочены по имени. Я работаю над статичным списком, поэтому я бы хотел работать на месте.

Пока мне удалось упорядочить список по одному свойству:

list.Sort((x, y) => x.Position.CompareTo(y.Position));

этот код работает, и у меня есть список, упорядоченный по позиции, но я не знаю, как реализовать вторую часть. Я нашел этот вопрос, но я не понимаю ответ.

Может ли кто-нибудь помочь мне?

3 ответа

Решение

Ответ, на который вы ссылаетесь, правильный. Ключ в сортировке по нескольким значениям заключается в том, что вторичное свойство имеет значение, только если основные цвета равны. Реализация psuedocode вашего сравнения сортировки может быть:

compare x and y position
if they differ, return order
else compare name, return order

На Sort метод, код после (x,y)=> должен возвращать 0, если элементы равны, отрицательное число, если первое должно быть перед вторым, и положительное число, если второе должно предшествовать первому. CompareTo Метод вернет -1, 0 или 1 на основе этих случаев и своих аргументов. Поскольку вам нужно сравнить два разных свойства, вам нужно два вызова CompareTo, Если вы решили добавить их вместе, у вас может быть такой случай:

  • x.position
  • x.name> y.name (сравнить возвращает 1)
  • результат 0, элементы считаются равными, где ваши правила четко говорят, что x должен стоять на первом месте в этом случае.

Чтобы решить эту проблему, мы должны убедиться, что сравнение Имени имеет значение только при равных позициях. поскольку CompareTo возвращает только -1, 0 или 1, если мы умножим результат позиции на 2 (или любое большее число), тогда сравнение Имени изменит только результат, если позиции равны. (Так как -2 + 1 = -1 а также 2 - 1 = 1)

Таким образом, используя метод в исходном связанном ответе, ваш код будет выглядеть примерно так:

list.Sort((x, y) => 
    2 * x.Position.CompareTo(y.Position) 
    + x.Name.CompareTo(y.Name));

Я бы использовал "OrderBy" и "ThenBy":

  IEnumerable<Person> orderedPersons = persons.OrderBy(item => item.Position)
            .ThenBy(item => item.Name);
list = list.OrderBy(item => item.Name).ToList();
list.Sort((x, y) => x.Position.CompareTo(y.Position));
Другие вопросы по тегам