2011-11-03 6 views
2

Итак, я выполняю задание для своего класса C#, и у меня есть список объектов. Эти объекты имеют поле «int rand», которому присваивается случайное число. Затем я хотел повторно сортировать объекты в списке на основе этого поля rand.Как сортировать список C# на основе свойства?

Я нашел эту статью: http://www.developerfusion.com/code/5513/sorting-and-searching-using-c-lists/

И это помогло. Я изменил эту строку, чтобы соответствовать моему коду:

people.Sort(delegate(Person p1, Person p2) { return p1.age.CompareTo(p2.age); }); 

И он делает то, что я хочу.

Что я хочу знать: как это работает? Это выглядит очень странно для меня.

+0

Обратите внимание, что это не самый эффективный способ перетасовать порядок элементов в списке. –

+0

Код вызовет ваш метод 'delegate (Person p1, Person p2) {return p1.age.CompareTo (p2.age); } 'на каждую пару элементов, которые он хочет сравнить. – Rob

+0

Возможный дубликат [C# - сортировка по свойству] (http://stackoverflow.com/questions/14147082/c-sharp-sorting-by-a-property) – DocMax

ответ

2

На самом деле метод сортировки должен сортировать базу при некотором сравнении, в вашем текущем коде вы прошли сравнение в качестве делегата, вы также можете встроить его в определение класса, чтобы уменьшить сложность кода. Фактически ему просто нужно было реализовать IComparable для вашего класса Person :

public class Person : IComparable 
    { 
     public int age { get; set; } 

     public int CompareTo(object obj) 
     { 
      var person = obj as Person; 
      if (person != null) 
      { 
       if (age > person.age) 
        return 1; 
       else if (age == person.age) 
        return 0; 
       return -1; 
      } 
      return 1; 
     } 
    } 

затем просто используйте сортировку без делегатов.

+0

Если его задание не требует от него использования делегатов, я бы сделал это тоже. – Tipx

+0

Это не всегда так, если вы хотите сортировать 'People' на' age' или 'name', в зависимости от выбора пользователя? –

+0

@ Мигель Анжело да, но хорошо иметь метод сравнения по умолчанию, а для других типов сравнения используют делегаты или лямбды. –

1

в списке будет использована функция, переданная в (return p1.age.CompareTo(p2.age);), для сравнения различных объектов в списке. Это в основном позволяет вам «научить» список, как вы хотите сравнить элементы.

Список будет вызывать вашу функцию, передавая в 2 экземплярах класса, который должен быть сопоставлен. вы возвращаете -1, чтобы сказать, что 1-й меньше, чем 2-й, 0, чтобы сказать, что они равны, и 1, чтобы сказать, что второй больше. Ваш пример просто передает вызов встроенному сравнению (который возвращает один и тот же шаблон -1, 0, 1) для любого типа возрастной переменной, скорее всего, целого.

0

Чтобы отсортировать, вы должны выяснить, есть ли у товара предмет до или после другой вещи. Имеет смысл, что этот «компаратор» будет функцией или методом, поскольку он отсекает знания.

Если вы посмотрите на документацию для CompareTo, вы заметите, что она предназначена для возврата -1 (B идет до A), 0, (A и B равны) или 1 (B идет после A).

The delegate keyword в этом случае создает анонимную функцию, которая используется в качестве компаратора, а тело этой функции вызывает CompareTo, чтобы сравнить возрастное свойство двух вовлеченных людей и вернуть результат.

Результат вызова этого метода для каждой потенциальной пары элементов (или некоторого подмножества - я точно не знаю, как реализовано Sort), затем используется методом Sort, чтобы выяснить, где разместить результирующий элемент (перед или позади p2) в этом примере.

0

List.Sort использует Quick sort algo для сортировки списка. Самая сложная проблема - O(n^2). Это означает, что в худшем случае предоставленный вами делегат будет называться n^2 раз, где n - это количество элементов в списке. Delegate - как указатель на функцию.

Он передает два объекта, которые он хочет сравнить, и предоставленный вами делегат вернется с -1, 0, или 1. Если его -1 означает, что p1 меньше, то p2, если 0 означает, что оба объекта одинаковы, если 1 означает, что p1 больше, чем p2.Итак, в конце концов, предоставленный вами делегат и возвращаемые значения будут определять, содержит ли список объекты в descending или ascending заказа.

2

При использовании лямбда-нотации с этим становится немного легче читать IMO:

people.Sort((p1, p2) => p1.age.CompareTo(p2.age)); 

При использовании метода сортировки вы сортировки списка, но метод должен знать, что для сортировки, и здесь делегация становится удобной, так как вы можете использовать метод сортировки, чтобы указать любую сортировку, которую вы хотите. Вы смотрите на человека 1 и человека 2 и заказываете по возрасту. Если вы хотите отсортировать чем-то другим, как имя (если вы имели свойство Имя), вы должны написать:

people.Sort((p1, p2) => string.Compare(p1.Name, p2.Name)); 
0

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

Метод сортировки:

Этот элемент принимает делегат, который содержит «как» сравнить два элемента списка. Как только вы научите список, как сравнивать с элементами, он может сортировать все элементы, сравнивая их попарно.

Рядный делегат

рядный делегат объявление метода, что делает что-то.

delegate(Person p1, Person p2) { return p1.age.CompareTo(p2.age); 

Этот делегат рассказывает, как сравнивать два объекта Person. Вы сообщаете это компилятору: для сравнения p1 с p2, вы должны сравнить p1.age с p2.age.

запрессовки вещи

Следующая строка кода содержит оба элемента, метод сортировки, а «как» сравнения двух человек объектов.

people.Sort(delegate(Person p1, Person p2) { return p1.age.CompareTo(p2.age); }); 

Теперь он знает, как отсортировать список.

Смежные вопросы