Упорядочение списка на месте по двум свойствам
У меня есть класс с двумя свойствами: Имя и Позиция. Я хотел бы упорядочить список с этим классом по позиции, а элементы с одинаковой позицией должны быть упорядочены по имени. Я работаю над статичным списком, поэтому я бы хотел работать на месте.
Пока мне удалось упорядочить список по одному свойству:
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));