2010-03-24 5 views
5

Ich habe eine Liste, wo Element ist:List <> eigene comparer

struct element { 
       double priority; 
       int value; 
       } 

Wie kann ich meine eigenen comparer implementieren, die mich Liste sortieren nach Priorität zulassen? Ich versuche, mit SortredList ... aber es nicht zulassen, dass douplicated Schlüssel :(

Vielen Dank für die Hilfe

+0

Welche Programmiersprache? –

+0

C#? Java? Was für eine Sprache? –

+2

wahrscheinlich C#, wegen der <> generic/template-Syntax, hat C++ nichts eingebautes genau namens 'List', und Java würde ArrayList bevorzugen. –

Antwort

3

Wenn Sie nicht verlassen können C# 3 Erweiterungen oder Lambdas dann können Sie Ihre Struktur die IComparable-Schnittstelle implementieren, etwa so:

struct element : IComparable 
{ 
    double priority; 
    int value; 
    public element(int val, double prio) 
    { 
     priority = prio; 
     value = val; 
    } 
    #region IComparable Members 

    public int CompareTo(object obj) 
    { 
     // throws exception if type is wrong 
     element other = (element)obj; 
     return priority.CompareTo(other.priority); 
    } 

    #endregion 
} 

Es gibt auch eine typesafe version dieser Schnittstelle, aber das Prinzip ist das gleiche

Nachdem Sie die Schnittstelle auf Ihrer Struktur oder Klasse implementiert haben, auf List<> die Sort Methode aufrufen wird „funktionieren“

static void Main(string[] args) 
{ 
    Random r = new Random(); 
    List<element> myList = new List<element>(); 
    for (int i = 0; i < 10; i++) 
     myList.Add(new element(r.Next(), r.NextDouble())); 
    // List is now unsorted 
    myList.Sort(); 
    // List is now sorted by priority 
    Console.ReadLine(); 
} 
+0

Sogar in 2.0 können Sie die anonyme Methode Ansatz, obwohl. –

+0

Große Implementierung! Danke für das Anwendungsbeispiel;) Das ist was ich brauche! :) – netmajor

+0

Marc: Ja du hast Recht. Ein Vorteil dieses Ansatzes ist jedoch, dass er automatisch für alle Orte funktioniert, an denen jemand eine Sammlung von Elementen sortieren muss. –

11

Unter der Annahme, C# 3 oder höher:

var sorted = MyList.OrderBy(e => e.priority); 
+0

Es sollte betont werden, dass dies ein neues 'IEnumerable <>' zurückgibt, anstatt die vorhandene 'List <>' direkt zu sortieren. – LukeH

+1

Beachten Sie, dass dadurch die Liste nicht sortiert wird. Bei der Iteration wird eine sortierte Liste Element für Element zurückgegeben. – Blindy

+0

Ich denke mehr über Sort-Methode, die Sammlung manipulieren und Ergebnis speichern. Aber Tnx auch dafür! Ich bin dankbar Ihre Hilfe :) – netmajor

1

Wenn Sie die Liste sortieren möchten ohne selbst eine neue Instanz zu erstellen, können Sie IComparer implementieren, rufen Sie dann List.Sort mit einer Instanz der Implementierung

public class ElementComparer : IComparer<element> 
{ 
    public int Compare(element x, element y) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+1

... mit 'neue NotImplementedException();' ersetzen durch 'return x.priority.CompareTo (y.priority);'! :) – gehho

+0

Ohne gehho Kommentar Deine Antwort ist partiell .. – netmajor

8

Sie können eine direkte Art durchführen, indem Sie die Sort overload, die eine Comparison<T> Delegierte nimmt:

yourList.Sort((x, y) => x.priority.CompareTo(y.priority)); 

Für ältere Versionen von C# müssen Sie die Lambda für Old-School-Delegat Syntax auszulagern:

yourList.Sort(
    delegate(element x, element y) { return x.priority.CompareTo(y.priority); }); 
+0

Ich bin dieses Zwei-Klassen-Weg-Sortierbeispiel geschätzt! – netmajor

+0

Ich kann den Lambda-Vorschlag nicht funktionieren lassen? Ich benutze 3,5, es sagt, kann Symbol nicht auflösen CompareTo – Robs

+1

Luzifer: wahrscheinlich aufgrund 'Priorität' ist ein privates Mitglied der' Element' Struktur –

2

Dies, wenn Sie hängt davon ab, möchte die Liste selbst sortieren oder die Werte in sortierter Reihenfolge abrufen (ohne die Liste zu ändern).

Um die Liste zu sortieren selbst (vorausgesetzt Sie haben eine List<element> genannt elements):

elements.Sort((x, y) => x.priority.CompareTo(y.priority)); 
// now elements is sorted 

.NET 2.0-Äquivalent:

elements.Sort(
    delegate(element x, element y) { 
     return x.priority.CompareTo(y.priority); 
    } 
); 

Um die Werte in sortierter Reihenfolge zu erhalten:

var orderedElements = elements.OrderBy(x => x.priority); 
// elements remains the same, but orderedElements will retrieve them in order 

Es gibt keine LINQ-Entsprechung in .NET 2.0, aber Sie können Ihre eigenen schreiben:

public static IEnumerable<T> OrderBy<T>(IEnumerable<T> source, Comparison<T> comparison) { 
    List<T> copy = new List<T>(source); 
    copy.Sort(comparison); 

    foreach (T item in copy) 
     yield return item; 
} 

Verbrauch:

Comparison<element> compareByPriority = delegate(element x, element y) { 
    return x.priority.CompareTo(y.priority); 
}; 

// unfortunately .NET 2.0 doesn't support extension methods, so this has to be 
// expressed as a regular static method 
IEnumerable<element> orderedElements = OrderBy(elements, compareByPriority); 
+0

Schöne Zusammenstellung aller Antworten: P – netmajor

Verwandte Themen