カスタムクラスリストを並べ替える<T>


112

dateプロパティでリストを並べ替えたいのですが。

これは私のカスタムクラスです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Test.Web
{
    public class cTag
    {
        public int id { get; set; }
        public int regnumber { get; set; }
        public string date { get; set; }
    }
}

これはList私がソートしたいものです:

List<cTag> Week = new List<cTag>();

私がしたいことはdate、cTagクラスのプロパティでリストをソートすることです。日付はdd.MM.yyyyの形式です。

IComparableインターフェースについて何か読みましたが、使い方がわかりません。

回答:


143

これを行う1つの方法は、 delegate

List<cTag> week = new List<cTag>();
// add some stuff to the list
// now sort
week.Sort(delegate(cTag c1, cTag c2) { return c1.date.CompareTo(c2.date); });

98
また、ラムダ式と同じことを書くことができますlist.Sort((a,b) => a.date.CompareTo(b.date));
ザビエルPoinas

2
@Xavierはなんらかの理由で、常に最初に述語にジャンプしますが、Lambda式で作業が完了し、おそらく読みやすく/理解しやすくなることは100%正確です。
ahsteele、2010

これはどうですか、またはどうやってラムダ式を使用して一貫してネクタイを破りますか?ここでa.date == b.dateの場合はどうなりますか?list.Sort((a、b)=> a.date.CompareTo(b.date)); これはページンググリッドとこれら2つが偶然異なるページにある場合に問題を引き起こしますか?
TheEmirOfGroofunkistan

1
@TheEmirOfGroofunkistanすべてのCompareTo実装方法に依存します。IComparableクラスがメソッドを持つことになる被付与者は、その比較をどのように行うかはクラス作成者次第です。DateがICompareをどのように実装するかはわかりませんが、値が等しい場合、開発者が渡された順序パラメーターを使用してタイを壊すことがよくあります。hth
ahsteele

51

cTagクラスがIComparable<T>インターフェイスを実装する必要があることは正しいです。その後Sort()、あなたのリストを呼び出すことができます。

IComparable<T>インターフェイスを実装するには、CompareTo(T other)メソッドを実装する必要があります。これを行う最も簡単な方法は、比較するフィールド(この場合は日付)のCompareToメソッドを呼び出すことです。

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public string date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

ただし、これは文字列に対して従来の並べ替えを使用するため(日付を文字列として宣言したため)、うまく並べ替えることはできません。したがって、クラスを再定義し、日付を文字列としてではなく、DateTimeとして宣言することが最善の方法だと思います。コードはほぼ同じままです。

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public DateTime date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

日付を含む文字列をDateTime型に変換するためにクラスのインスタンスを作成するときに行う必要があることは1つだけですが、たとえばDateTime.Parse(String)メソッドによって簡単に実行できます。


38

この場合、LINQを使用して並べ替えることもできます。

week = week.OrderBy(w => DateTime.Parse(w.date)).ToList();

12
List<cTag> week = new List<cTag>();
week.Sort((x, y) => 
    DateTime.ParseExact(x.date, "dd.MM.yyyy", CultureInfo.InvariantCulture).CompareTo(
    DateTime.ParseExact(y.date, "dd.MM.yyyy", CultureInfo.InvariantCulture))
);

9

まず最初に、dateプロパティが日付を格納している場合は、DateTimeを使用して格納します。並べ替えを通じて日付を解析する場合、比較される各アイテムについて日付を解析する必要がありますが、それはあまり効率的ではありません...

次に、IComparerを作成できます。

public class TagComparer : IComparer<cTag>
{
    public int Compare(cTag first, cTag second)
    {
        if (first != null && second != null)
        {
            // We can compare both properties.
            return first.date.CompareTo(second.date);
        }

        if (first == null && second == null)
        {
            // We can't compare any properties, so they are essentially equal.
            return 0;
        }

        if (first != null)
        {
            // Only the first instance is not null, so prefer that.
            return -1;
        }

        // Only the second instance is not null, so prefer that.
        return 1;
    }
}

var list = new List<cTag>();
// populate list.

list.Sort(new TagComparer());

デリゲートとしても実行できます。

list.Sort((first, second) =>
          {
              if (first != null && second != null)
                  return first.date.CompareTo(second.date);

              if (first == null && second == null)
                  return 0;

              if (first != null)
                  return -1;

              return 1;
          });

6

あなたは正しいです-あなたはIComparableを実装する必要があります。これを行うには、クラスを宣言します。

public MyClass : IComparable
{
  int IComparable.CompareTo(object obj)
  {
  }
}

CompareToでは、カスタム比較アルゴリズムを実装するだけです(これを行うには、DateTimeオブジェクトを使用できますが、最初に「obj」のタイプを確認してください)。詳細については、ここここを参照ください


7
IComparable<T>それはに優先してチェックされて、おそらく、より良い選択であるIComparablemsdn.microsoft.com/en-us/library/b0zbh7b6.aspx
リチャードSZALAY

5

linqを使用できます。

var q = from tag in Week orderby Convert.ToDateTime(tag.date) select tag;
List<cTag> Sorted = q.ToList()

3

ListクラスのオーバーロードされたSortメソッドを見てください。それにはいくつかの方法があります。それらの1つ:カスタムクラスはIComparableインターフェイスを実装する必要があり、ListクラスのSortメソッドを使用できます。


3

すべての速い答えをありがとう。

これは私の解決策です:

Week.Sort(delegate(cTag c1, cTag c2) { return DateTime.Parse(c1.date).CompareTo(DateTime.Parse(c2.date)); });

ありがとう


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.