简体   繁体   English

在 C# 中对对象列表进行排序

[英]Sorting a List of objects in C#

public class CarSpecs
{
  public String CarName { get; set; }

  public String CarMaker { get; set; }

  public DateTime CreationDate { get; set; }
}

This is a list and I am trying to figure out an efficient way to sort this list List CarList, containing 6(or any integer amount) Cars, by the Car Make Date.这是一个列表,我试图找出一种有效的方法来按汽车制造日期对这个列表 CarList 进行排序,其中包含 6 个(或任何整数)汽车。 I was going to do Bubble sort, but will that work?我打算做冒泡排序,但这行得通吗? Any Help?任何帮助?

Thanks谢谢

The List<T> class makes this trivial for you, since it contains a Sort method . List<T>类对您来说很简单,因为它包含一个Sort方法 (It uses the QuickSort algorithm, not Bubble Sort, which is typically better anyway.) Even better, it has an overload that takes a Comparison<T> argument, which means you can pass a lambda expression and make things very simple indeed. (它使用 QuickSort 算法,而不是通常更好的冒泡排序算法。)更棒的是,它有一个采用Comparison<T>参数的重载,这意味着您可以传递一个 lambda 表达式并使事情变得非常简单。

Try this:试试这个:

CarList.Sort((x, y) => DateTime.Compare(x.CreationDate, y.CreationDate));

You could use LINQ:你可以使用 LINQ:

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

EDIT: With this approach, its easy to add on more sort columns:编辑:使用这种方法,可以轻松添加更多排序列:

listOfCars.OrderBy(x => x.CreationDate).ThenBy(x => x.Make).ThenBy(x => x.Whatever);

The best approach is to implement eitherIComparable or IComparable<T> , and then call List<T>.Sort() .最好的方法是实现IComparableIComparable<T> ,然后调用List<T>.Sort() This will do all the hard work of sorting for you.这将为您完成所有繁重的排序工作。

Another option would be to use a custom comparer:另一种选择是使用自定义比较器:

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
   }
}

which you call like this:你这样称呼它:

yourCarlist.Sort(new CarNameComparer());

Note: I didn't compile this code so you might have to remove typo's注意:我没有编译这段代码,所以你可能需要删除错字

Edit: modified it so the comparer compares on creationdate as requested in question.编辑:修改它,以便比较器按照有问题的要求在创建日期进行比较。

I would just use the build in List.Sort method.我只会使用 List.Sort 方法中的构建。 It uses the QuickSort algorithm which on average runs in O(n log n).它使用平均运行时间为 O(n log n) 的 QuickSort 算法。

This code should work for you, I change your properties to auto-properties, and defined a static CompareCarSpecs method that just uses the already existing DateTime.CompareTo method.此代码应该对您有用,我将您的属性更改为自动属性,并定义了一个静态 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);
    }
}

Hope this helps.希望这可以帮助。

Putting some of the pieces mentioned here together.将这里提到的一些部分放在一起。 This compiles and works in C# 4.x and VS2010.这在 C# 4.x 和 VS2010 中编译和工作。 I tested with a WinForm .我用WinForm进行了测试。 So add the method to the WinForm Main() .因此,将方法添加到WinForm Main() You will need the System.Linq and System.Generic.Collection s assemblies at least.您至少需要System.LinqSystem.Generic.Collection的程序集。

    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; }
} 

If you're after an efficient way of sorting, I'd advise against using bubble sort and go for a quick sort instead.如果您追求的是一种高效的排序方式,我建议您不要使用冒泡排序,而是使用快速排序。 This page provides a rather good explanation of the algorithm:此页面提供了对该算法的相当好的解释:

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

Best of luck!祝你好运!

我会避免编写自己的排序算法,但是如果您打算这样做,请查看http://www.sorting-algorithms.com/以了解不同排序算法的一些比较...

如果您使用的是 2.0,以下讨论可能有用: C# List<> Sort by x then y

If you use delegates (also known as anonymous methods), you won't have to implement any IComparer / IComparable interfaces.如果使用委托(也称为匿名方法),则不必实现任何 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;
        });

    }

To extend the answer of Noldorin, in order to sort a list with int datatype this can be used:为了扩展 Noldorin 的答案,为了使用 int 数据类型对列表进行排序,可以使用:

listName.Sort((x, y) =>  x.CompareTo(y));

Or if you have a complex object in the list:或者,如果列表中有一个复杂的对象:

inventoryList.Sort((x, y) =>  x.stockNumber.CompareTo(y.stockNumber));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM