[C#] 개체의 속성별로 List <T>를 정렬하는 방법

나는라는 클래스가 Order속성 등이 OrderId, OrderDate, Quantity,와 Total. 이 Order수업 목록이 있습니다 .

List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders

이제 Order객체 의 한 속성을 기준으로 목록을 정렬하려고합니다. 예를 들어 주문 날짜 또는 주문 ID별로 정렬해야합니다.

C #에서 어떻게 할 수 있습니까?



답변

내가 생각할 수있는 가장 쉬운 방법은 Linq를 사용하는 것입니다.

List<Order> SortedList = objListOrder.OrderBy(o=>o.OrderDate).ToList();


답변

목록을 적절하게 정렬 해야하는 경우 대리자를 Sort전달 하여 메소드를 사용할 수 있습니다 Comparison<T>.

objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

제자리에서 정렬하는 대신 새로운 정렬 된 시퀀스를 만드는 것을 선호한다면 OrderBy다른 답변에서 언급 한 것처럼 LINQ의 방법을 사용할 수 있습니다 .


답변

.Net2.0에서 LINQ없이이 작업을 수행하려면

List<Order> objListOrder = GetOrderList();
objListOrder.Sort(
    delegate(Order p1, Order p2)
    {
        return p1.OrderDate.CompareTo(p2.OrderDate);
    }
);

.Net3.0을 사용하는 경우 LukeH의 대답 은 당신이 따르는 입니다.

여러 속성을 정렬하려면 대리인 내에서 계속 수행 할 수 있습니다. 예를 들면 다음과 같습니다.

orderList.Sort(
    delegate(Order p1, Order p2)
    {
        int compareDate = p1.Date.CompareTo(p2.Date);
        if (compareDate == 0)
        {
            return p2.OrderID.CompareTo(p1.OrderID);
        }
        return compareDate;
    }
);

이렇게하면 내림차순 으로 날짜가 오름차순으로 표시됩니다.

그러나 코드 재사용이없는 많은 장소를 의미하기 때문에 대표를 고수하지 않는 것이 좋습니다. 를 구현하고 메소드에 IComparer전달해야합니다 Sort. 여기를 참조 하십시오 .

public class MyOrderingClass : IComparer<Order>
{
    public int Compare(Order x, Order y)
    {
        int compareDate = x.Date.CompareTo(y.Date);
        if (compareDate == 0)
        {
            return x.OrderID.CompareTo(y.OrderID);
        }
        return compareDate;
    }
}

그런 다음이 IComparer 클래스를 사용하려면 인스턴스화하여 Sort 메서드에 전달하십시오.

IComparer<Order> comparer = new MyOrderingClass();
orderList.Sort(comparer);


답변

목록을 주문하는 가장 간단한 방법은 OrderBy

 List<Order> objListOrder =
    source.OrderBy(order => order.OrderDate).ToList();

다음 SQL 쿼리와 같은 여러 열로 주문하려는 경우.

ORDER BY OrderDate, OrderId

이를 달성하기 위해 ThenBy다음과 같이 사용할 수 있습니다 .

  List<Order> objListOrder =
    source.OrderBy(order => order.OrderDate).ThenBy(order => order.OrderId).ToList();


답변

당신이 말한대로 Linq없이 그것을하는 것 :

public class Order : IComparable
{
    public DateTime OrderDate { get; set; }
    public int OrderId { get; set; }

    public int CompareTo(object obj)
    {
        Order orderToCompare = obj as Order;
        if (orderToCompare.OrderDate < OrderDate || orderToCompare.OrderId < OrderId)
        {
            return 1;
        }
        if (orderToCompare.OrderDate > OrderDate || orderToCompare.OrderId > OrderId)
        {
            return -1;
        }

        // The orders are equivalent.
        return 0;
    }
}

그런 다음 주문 목록에서 .sort ()를 호출하십시오.


답변

고전적인 객체 지향 솔루션

먼저 LINQ의 훌륭함을 기뻐해야합니다. 이제 우리는 그 길을 벗어났습니다.

JimmyHoffa의 변형입니다. 제네릭을 사용하면 CompareTo매개 변수가 형식이 안전 해집니다.

public class Order : IComparable<Order> {

    public int CompareTo( Order that ) {
        if ( that == null ) return 1;
        if ( this.OrderDate > that.OrderDate) return 1;
        if ( this.OrderDate < that.OrderDate) return -1;
        return 0;
    }
}

// in the client code
// assume myOrders is a populated List<Order>
myOrders.Sort(); 

이 기본 정렬은 물론 재사용 할 수 있습니다. 즉, 각 클라이언트는 정렬 논리를 중복해서 다시 작성할 필요가 없습니다. “1”과 “-1″(또는 선택한 논리 연산자)을 바꾸면 정렬 순서가 반대로됩니다.


답변

// gridview와 함께 사용하기위한 완전히 일반적인 정렬

public List<T> Sort_List<T>(string sortDirection, string sortExpression, List<T> data)
    {

        List<T> data_sorted = new List<T>();

        if (sortDirection == "Ascending")
        {
            data_sorted = (from n in data
                              orderby GetDynamicSortProperty(n, sortExpression) ascending
                              select n).ToList();
        }
        else if (sortDirection == "Descending")
        {
            data_sorted = (from n in data
                              orderby GetDynamicSortProperty(n, sortExpression) descending
                              select n).ToList();

        }

        return data_sorted;

    }

    public object GetDynamicSortProperty(object item, string propName)
    {
        //Use reflection to get order type
        return item.GetType().GetProperty(propName).GetValue(item, null);
    }