사용자 지정 클래스 목록 정렬 <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 클래스 의 속성 별로 List를 정렬하는 것 입니다. 날짜 형식은 dd.MM.yyyy입니다.

IComparable인터페이스 에 대해 읽었 지만 사용 방법을 모르겠습니다.

답변:


143

이를 수행하는 한 가지 방법은 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-07-02

어떻게 이것이 람다 식을 사용하여 일관되게 넥타이를 끊을 것인가? a.date == b.date 여기에? list.Sort ((a, b) => a.date.CompareTo (b.date)); 페이징 그리드가 다른 페이지에있을 때 문제가 발생합니까?
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 유형으로 변환하기 위해 클래스의 인스턴스를 만들 때해야 할 일만 있지만, 예를 들어 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

먼저 날짜 속성이 날짜를 저장하는 경우 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>이에 우선 검사대로 아마, 더 나은 선택이 될 것입니다 IComparable: msdn.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 메서드를 살펴보십시오. 그것에 대한 몇 가지 방법이 있습니다. 그중 하나 : 사용자 지정 클래스는 IComparable 인터페이스를 구현해야하며 List 클래스의 Sort 메서드를 사용합니다.


3

모든 빠른 답변에 감사드립니다.

이것이 내 해결책입니다.

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

감사


2
YourVariable.Sort((a, b) => a.amount.CompareTo(b.amount));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.