Sortieren Sie eine Liste alphabetisch

83

Ich habe folgende Klasse:

class Detail
{
    public Detail()
    {
        _details = new List<string>();
    }
    public IList<string> Details { get { return _details; } }
    private readonly List<string> _details;
}

Derzeit sortiere ich die Klasse nach dem Zufallsprinzip wie folgt:

void ShuffleGenericList<T>(IList<T> list)
{
    //generate a Random instance
    var rnd = new Random();
    //get the count of items in the list
    var i = list.Count();
    //do we have a reference type or a value type
    T val = default(T);

    //we will loop through the list backwards
    while (i >= 1)
    {
        //decrement our counter
        i--;
        //grab the next random item from the list
        var nextIndex = rnd.Next(i, list.Count());
        val = list[nextIndex];
        //start swapping values
        list[nextIndex] = list[i];
        list[i] = val;
    }
}

Was ich tun möchte, ist, den Inhalt von Details in alphabetischer Reihenfolge zu sortieren.

Zum Beispiel, wenn der Inhalt so aussieht:

[0] a
[1] d
[2] b

Ich möchte in der Lage sein, diese Methode auszuführen und sie sortieren zu lassen:

[0] a
[1] b
[2] d

Kennt jemand einen einfachen Weg, dies zu tun? Beachten Sie, dass die Listen normalerweise weniger als zehn Einträge enthalten. Kann ich das mit LINQ machen? Entschuldigung, aber ich bin nicht sehr vertraut mit LINQ. Ich habe gerade einen Vorschlag gehört, dass ich das verwenden könnte.

Mariko
quelle

Antworten:

154

Sie können eine Liste sortieren , an Ort und Stelle nur durch den Aufruf List<T>.Sort:

list.Sort();

Dabei wird die natürliche Reihenfolge der Elemente verwendet, was in Ihrem Fall in Ordnung ist.

BEARBEITEN: Beachten Sie, dass Sie in Ihrem Code benötigen

_details.Sort();

da die SortMethode nur in definiert ist List<T>, nicht IList<T>. Wenn Sie es von außen sortieren müssen, wo Sie keinen Zugriff darauf haben List<T>(Sie sollten es nicht umwandeln, da das List<T>Teil ein Implementierungsdetail ist), müssen Sie etwas mehr Arbeit leisten.

Ich kenne keine IList<T>In-Place-Sorten in .NET, was etwas seltsam ist, jetzt denke ich darüber nach. IList<T>bietet alles , was man braucht, so dass es könnte als Erweiterung Methode geschrieben werden. Es gibt viele Quicksort-Implementierungen, wenn Sie eine davon verwenden möchten.

Wenn Sie sich nicht für ein bisschen Ineffizienz interessieren, können Sie immer Folgendes verwenden:

public void Sort<T>(IList<T> list)
{
    List<T> tmp = new List<T>(list);
    tmp.Sort();
    for (int i = 0; i < tmp.Count; i++)
    {
        list[i] = tmp[i];
    }
}

Mit anderen Worten, kopieren Sie, sortieren Sie an Ort und Stelle und kopieren Sie dann die sortierte Liste zurück.


Mit LINQ können Sie eine neue Liste erstellen, die die ursprünglichen Werte enthält, aber sortiert ist:

var sortedList = list.OrderBy(x => x).ToList();

Es kommt darauf an, welches Verhalten Sie wollen. Beachten Sie, dass Ihre Shuffle-Methode nicht wirklich ideal ist:

  • Das Erstellen einer neuen RandomMethode führt zu einigen der hier gezeigten Probleme
  • Sie können valinnerhalb der Schleife deklarieren - Sie verwenden diesen Standardwert nicht
  • Es ist idiomatischer, die CountEigenschaft zu verwenden, wenn Sie wissen, dass Sie mit einem arbeitenIList<T>
  • Meiner Meinung nach ist eine forSchleife einfacher zu verstehen, als die Liste mit einer whileSchleife rückwärts zu durchlaufen

Es gibt andere Implementierungen des Mischens mit Fisher-Yates bei Stapelüberlauf - suchen Sie und Sie werden ziemlich schnell eine finden.

Jon Skeet
quelle
Wenn ich also die oben erstellte Liste sortieren möchte, muss ich dann nur sagen: sortedList.Sort?
Mariko
Ich habe die Sortierung versucht, kann sie aber nicht zum Laufen bringen. - Meine Liste sieht folgendermaßen aus: IList <string> nD. Ich habe nD.Sort () ausprobiert, aber es heißt: Das Symbol 'Sortieren' kann nicht aufgelöst werden.
Mariko
@ Mariko: Verwenden Sie _details.Sort()stattdessen - wie _detailsals List<string>eher als deklariert IList<string>. Sortwird nur deklariert List<T>, nicht IList<T>.
Jon Skeet
24

Es gibt zwei Möglichkeiten:

Ohne LINQ: yourList.Sort();

Mit LINQ: yourList.OrderBy(x => x).ToList()

Weitere Informationen finden Sie unter: http://www.dotnetperls.com/sort-string-array

Damiox
quelle
@Dminox - Meine Liste sieht folgendermaßen aus: IList <string> nD. Ich habe nD.Sort () ausprobiert, aber es heißt: Das Symbol 'Sortieren' kann nicht aufgelöst werden.
Mariko
1
@ Mariko Sort()ist Mitglied von List<T> nicht IList<T> . Sie könnten in Betracht ziehen, zu ersteren zu wechseln (es sei denn, Sie erwarten, mit verschiedenen IList<T>Implementierungen zu arbeiten.)
dlev
23

Ein anderer Weg

_details.Sort((s1, s2) => s1.CompareTo(s2)); 
Lahsrah
quelle
10
Dieser hat den Vorteil, dass er sich an die Sortierung eines Objekts nach einer seiner Eigenschaften anpassen kann .
MGOwen
11

Sie sollten in der Lage sein, OrderByin LINQ zu verwenden ...

var sortedItems = myList.OrderBy(s => s);
Quintin Robinson
quelle
2
Hinweis: das kehrt zurück IEnumerable<T>und ist nicht an Ort und Stelle sortiert
abatishchev
1

Was ist los mit List<T>.Sort()?

http://msdn.microsoft.com/en-us/library/3da4abas.aspx

Oleg Dudnyk
quelle
@goril - Ich möchte dies verwenden, erhalte aber eine Fehlermeldung. Dies ist, was ich dem anderen Kommentar hinzugefügt habe. Ich hoffe, Sie können helfen - Meine Liste sieht folgendermaßen aus: IList <string> nD. Ich habe nD.Sort () ausprobiert, aber es heißt: Das Symbol 'Sortieren' kann nicht aufgelöst werden.
Mariko
1
@Mariko: Sie verwenden die Schnittstelle IList <T>, die keine Sortiermethode enthält. Sortieren Sie die Variable List <T> direkt. Mit anderen Worten, Sie können _detailsaus Ihrem Beispiel sortieren, aber nichtDetails
Oleg Dudnyk