Сортировка списка объектов в C # - PullRequest
37 голосов
/ 29 мая 2009
public class CarSpecs
{
  public String CarName { get; set; }

  public String CarMaker { get; set; }

  public DateTime CreationDate { get; set; }
}

Это список, и я пытаюсь найти эффективный способ сортировки этого списка. Список CarList, содержащий 6 (или любое целое число) автомобилей, по дате создания автомобиля. Я собирался сделать Bubble, но будет ли это работать? Любая помощь?

Спасибо

Ответы [ 10 ]

85 голосов
/ 29 мая 2009

Класс List<T> делает это тривиальным для вас, так как он содержит Sort метод . (Он использует алгоритм быстрой сортировки, а не Bubble Sort, который, как правило, лучше в любом случае.) Более того, он имеет перегрузку, которая принимает аргумент Comparison<T>, что означает, что вы можете передать лямбда-выражение и упростить задачу.

Попробуйте это:

CarList.Sort((x, y) => DateTime.Compare(x.CreationDate, y.CreationDate));
57 голосов
/ 29 мая 2009

Вы можете использовать LINQ:

listOfCars.OrderBy(x => x.CreationDate);

РЕДАКТИРОВАТЬ: При таком подходе легко добавить больше столбцов сортировки:

listOfCars.OrderBy(x => x.CreationDate).ThenBy(x => x.Make).ThenBy(x => x.Whatever);
16 голосов
/ 29 мая 2009

Наилучшим подходом является реализация либо IComparable или IComparable<T>, а затем вызов List<T>.Sort(). Это сделает всю тяжелую работу по сортировке за вас.

14 голосов
/ 29 мая 2009

Другой вариант - использовать пользовательский компаратор:

using System;
using System.Collections.Generic;
using System.Text;

namespace Yournamespace
{
   class CarNameComparer : IComparer<Car>
   {
      #region IComparer<Car> Members

      public int Compare(Car car1, Car car2)
      {
         int returnValue = 1;
         if (car1 != null && car2 == null)
         {
            returnValue = 0;
         }
         else if (car1 == null && car2 != null)
         {
            returnValue = 0;
         }
         else if (car1 != null && car2 != null)
         {
            if (car1.CreationDate.Equals(car2.CreationDate))
            {
               returnValue = car1.Name.CompareTo(car2.Name);
            }
            else
            {
               returnValue = car2.CreationDate.CompareTo(car1.CreationDate);
            }
         }
         return returnValue;
      }

      #endregion
   }
}

который вы называете так:

yourCarlist.Sort(new CarNameComparer());

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

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

6 голосов
/ 29 мая 2009

Я бы просто использовал метод построения в List.Sort. Он использует алгоритм быстрой сортировки, который в среднем работает за O (n log n).

Этот код должен работать для вас, я изменил ваши свойства на авто-свойства и определил статический метод CompareCarSpecs, который просто использует уже существующий метод DateTime.CompareTo.

class Program
{
    static void Main(string[] args)
    {
        List<CarSpecs> cars = new List<CarSpecs>();
        cars.Sort(CarSpecs.CompareCarSpecs);
    }
}

public class CarSpecs
{
    public string CarName { get; set; }
    public string CarMaker { get; set; }
    public DateTime CreationDate { get; set; }

    public static int CompareCarSpecs(CarSpecs x, CarSpecs y)
    {
        return x.CreationDate.CompareTo(y.CreationDate);
    }
}

Надеюсь, это поможет.

3 голосов
/ 09 мая 2012

Собираем некоторые из упомянутых здесь частей вместе. Это компилируется и работает в C # 4.x и VS2010. Я проверил с WinForm. Так что добавьте метод к WinForm Main(). Вам понадобятся сборки System.Linq и System.Generic.Collection s как минимум.

    private void SortCars()
    {
        List<CarSpecs> cars = new List<CarSpecs>();
        List<CarSpecs> carsSorted = new List<CarSpecs>();

        cars.Add(new CarSpecs
        {
            CarName = "Y50",
            CarMaker = "Ford",
            CreationDate = new DateTime(2011, 4, 1),
        });

        cars.Add(new CarSpecs
        {
            CarName = "X25",
            CarMaker = "Volvo",
            CreationDate = new DateTime(2012, 3, 1),
        });

        cars.Add(new CarSpecs
        {
            CarName = "Z75",
            CarMaker = "Datsun",
            CreationDate = new DateTime(2010, 5, 1),
        });

        //More Comprehensive if needed  
        //cars.OrderBy(x => x.CreationDate).ThenBy(x => x.CarMaker).ThenBy(x => x.CarName);

        carsSorted.AddRange(cars.OrderBy(x => x.CreationDate));

        foreach (CarSpecs caritm in carsSorted)
        {
            MessageBox.Show("Name: " +caritm.CarName 
                + "\r\nMaker: " +caritm.CarMaker
                + "\r\nCreationDate: " +caritm.CreationDate);
        }
    }
}

public class CarSpecs
{
    public string CarName { get; set; }
    public string CarMaker { get; set; }
    public DateTime CreationDate { get; set; }
} 
1 голос
/ 29 мая 2009

Если вы используете 2.0, может пригодиться следующее обсуждение: C # List <> Сортировать по x, затем y

1 голос
/ 29 мая 2009

Я бы не стал писать свой собственный алгоритм сортировки, но если вы все равно собираетесь, посмотрите http://www.sorting -algorithms.com / , где приведены некоторые сравнения различных алгоритмов сортировки ...

1 голос
/ 29 мая 2009

Если вам нужен эффективный способ сортировки, я бы посоветовал не использовать пузырьковую сортировку и вместо этого пойти на быструю сортировку. Эта страница дает довольно хорошее объяснение алгоритма:

http://www.devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=574

Удачи!

0 голосов
/ 18 мая 2018

Если вы используете делегаты (также известные как анонимные методы), вам не потребуется реализовывать какие-либо интерфейсы IComparer / IComparable.

public static void Main(string[] args)
    {


      List<CarSpecs> list = new List<CarSpecs>();

      list.Add(new CarSpecs("Focus", "Ford", new DateTime(2010,1, 2));
      list.Add(new CarSpecs("Prius", "Toyota", new DateTime(2012,3, 3));
      list.Add(new CarSpecs("Ram", "Dodge", new DateTime(2013, 10, 6));



        list.Sort(delegate (CarSpecs first, CarSpecs second)
        {
            int returnValue = 1;
            if((first != null & second != null))
            {
                if (first.CarName.Equals(second.CarName))
                {
                    if (first.CarMaker.Equals(second.CarMaker))
                    {
                    returnValue = first.CreationDate.CompareTo(second.CreationDate);
                    }
                    else
                    {
                    returnValue = first.CarMaker.CompareTo(second.CarMaker);
                    }
                }
                else
                {
                    returnValue = first.CarName.CompareTo(second.CarName);
                }
            }
            return returnValue;
        });

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