Frage So sortieren Sie eine Liste nach einer Eigenschaft im Objekt


Ich habe eine Klasse namens Order welches Eigenschaften wie hat OrderId, OrderDate, Quantity, und Total. Ich habe eine Liste davon Order Klasse:

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

Jetzt möchte ich die Liste basierend auf einer Eigenschaft der Order Objekt, zum Beispiel muss ich es nach dem Bestelldatum oder Auftrags-ID sortieren.

Wie kann ich das in C # tun?


902
2017-07-22 13:13


Ursprung


Antworten:


Der einfachste Weg, an den ich denken kann, ist Linq zu verwenden:

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

1328
2017-07-22 13:16



Wenn Sie die Liste an Ort und Stelle sortieren müssen, können Sie die Sort Methode, übergeben a Comparison<T> delegieren:

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

Wenn Sie lieber eine neue, sortierte Sequenz erstellen möchten, anstatt sie direkt zu sortieren, können Sie LINQs verwenden OrderBy Methode, wie in den anderen Antworten erwähnt.


501
2017-07-22 13:23



Um dies ohne LINQ auf .Net2.0 zu tun:

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

Wenn Sie auf .Net3.0 sind, dann ist LukeH Antworten ist was du willst.

Um nach mehreren Eigenschaften zu sortieren, können Sie dies immer noch innerhalb eines Delegaten tun. Beispielsweise:

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

Das würde dir geben aufsteigend Termine mit absteigend Bestell-IDs

Ich würde jedoch nicht empfehlen, Delegierte festzuhalten, da dies viele Orte ohne Code-Wiederverwendung bedeutet. Sie sollten ein implementieren IComparer und übergib das einfach an deine Sort Methode. Sehen Hier.

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

Um diese IComparer-Klasse zu verwenden, müssen Sie sie einfach instanziieren und an Ihre Sort-Methode übergeben:

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

197
2017-07-22 13:35



Der einfachste Weg, eine Liste zu bestellen, ist zu verwenden OrderBy

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

Wenn Sie nach mehreren Spalten sortieren möchten, z. B. nach der SQL-Abfrage.

ORDER BY OrderDate, OrderId

Um dies zu erreichen, können Sie verwenden ThenBy wie folgt.

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

76
2017-07-22 13:23



Mach es ohne Linq wie du gesagt hast:

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

Dann rufen Sie einfach .sort () auf Ihrer Liste der Bestellungen


31
2017-07-22 13:55



Eine klassische objektorientierte Lösung

Zuerst muss ich mich zu der Großartigkeit von LINQ beugen ... Jetzt haben wir das aus dem Weg geschafft

Eine Variation von JimmyHoffa Antwort. Mit Generika die CompareTo Parameter wird typsicher.

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

Diese Standardsortierbarkeit ist natürlich wiederverwendbar. Das bedeutet, dass jeder Client die Sortierlogik nicht redundant neu schreiben muss. Durch das Tauschen der "1" und "-1" (oder der logischen Operatoren, die Sie ausgewählt haben) wird die Sortierreihenfolge umgekehrt.


19
2017-10-16 14:03



// Völlig generische Sortierung zur Verwendung mit einer 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);
    }

15
2018-06-13 01:37



Hier ist eine generische LINQ-Erweiterungsmethode, die keine zusätzliche Kopie der Liste erstellt:

public static void Sort<T,U>(this List<T> list, Func<T, U> expression)
    where U : IComparable<U>
{
    list.Sort((x, y) => expression.Invoke(x).CompareTo(expression.Invoke(y)));
}

Um es zu benutzen:

myList.Sort(x=> x.myProperty);

Ich habe vor kurzem diesen zusätzlichen gebaut, der ein akzeptiert ICompare<U>, damit Sie den Vergleich anpassen können. Dies war nützlich, wenn ich eine Natural-String-Sortierung durchführen musste:

public static void Sort<T, U>(this List<T> list, Func<T, U> expression, IComparer<U> comparer)
    where U : IComparable<U>
{    
    list.Sort((x, y) => comparer.Compare(expression.Invoke(x), expression.Invoke(y)));
}

5
2018-02-14 14:25



Verwenden von LINQ

objListOrder = GetOrderList()
                   .OrderBy(o => o.OrderDate)
                   .ToList();

objListOrder = GetOrderList()
                   .OrderBy(o => o.OrderId)
                   .ToList();

3
2017-07-22 13:16



//Get data from database, then sort list by staff name:

List<StaffMember> staffList = staffHandler.GetStaffMembers();

var sortedList = from staffmember in staffList
                 orderby staffmember.Name ascending
                 select staffmember;

3
2017-11-23 21:42