web-dev-qa-db-ja.com

C#でオブジェクトのリストを並べ替える

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

  public String CarMaker { get; set; }

  public DateTime CreationDate { get; set; }
}

これはリストであり、6(または任意の整数量)の車を含むこのリストをCar Make Dateでソートする効率的な方法を見つけようとしています。私はバブルソートを行うつもりでしたが、それは機能しますか?ヘルプはありますか?

ありがとう

37
Mike Gallager

List<T>クラスには Sortメソッド が含まれているため、これは簡単です。 (とにかく一般的に優れているバブルソートではなく、QuickSortアルゴリズムを使用します。)さらに良いことに、Comparison<T>引数。これは、ラムダ式を渡して、実際に非常に単純にすることができることを意味します。

これを試して:

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

LINQを使用できます。

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

編集:このアプローチを使用すると、ソート列を簡単に追加できます。

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

最適なアプローチは、 IComparable または _IComparable<T>_ 、次に List<T>.Sort() を呼び出します。これにより、ソートの面倒な作業がすべて行われます。

16
Andy

別のオプションは、カスタム比較子を使用することです。

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());

注:このコードはコンパイルしなかったため、タイプミスを削除する必要がある場合があります。

編集:質問で要求されたように、比較者が作成日に比較するように変更しました。

14
Peter

List.Sortメソッドでビルドを使用するだけです。これは、平均でO(n log n)で実行されるQuickSortアルゴリズムを使用します。

このコードはあなたのために働くはずです、私はあなたのプロパティを自動プロパティに変更し、既存のDateTime.CompareToメソッドを使用するだけの静的CompareCarSpecsメソッドを定義しました。

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

お役に立てれば。

6
Egil Hansen

ここに記載されているいくつかのピースをまとめます。これは、C#4.xおよびVS2010でコンパイルおよび動作します。 WinFormでテストしました。そのため、WinFormMain()にメソッドを追加します。少なくともSystem.LinqおよびSystem.Generic.Collectionsアセンブリが必要です。

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

効率的な並べ替え方法をお望みの場合は、バブルソートの使用をお勧めせず、代わりにクイックソートをお勧めします。このページは、アルゴリズムのかなり良い説明を提供します:

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

幸運を祈ります!

1
Mia Clarke

私は独自のソートアルゴリズムを書くことを避けますが、とにかくしようとしている場合は、 http://www.sorting-algorithms.com/ で異なるソートアルゴリズムの比較をご覧ください...

1
Arjan Einbu

2.0を使用している場合、次の説明が役立つ場合があります。 C#List <> Sort by x then y

1
Byron Ross

デリゲート(匿名メソッドとも呼ばれます)を使用する場合、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;
        });

    }
0
Mark Woodard