wake-up-neo.com

So sortieren Sie eine IEnumerable <Zeichenfolge>

Wie kann ich einen IEnumerable<string> Alphabetisch sortieren? Ist das möglich?

Edit: Wie würde ich eine In-Place-Lösung schreiben?

87
CatZilla

So wie Sie jede andere Aufzählung sortieren würden:

var result = myEnumerable.OrderBy(s => s);

oder

var result = from s in myEnumerable
             orderby s
             select s;

oder (Groß-/Kleinschreibung ignorieren)

var result = myEnumerable.OrderBy(s => s,
                                  StringComparer.CurrentCultureIgnoreCase);

Beachten Sie, dass wie bei LINQ üblich ein neues IEnumerable <T> erstellt wird, das bei Aufzählung die Elemente des ursprünglichen IEnumerable <T> in sortierter Reihenfolge zurückgibt. IEnumerable <T> wird nicht direkt sortiert.


Ein IEnumerable <T> ist schreibgeschützt, dh, Sie können nur die Elemente daraus abrufen, aber nicht direkt ändern. Wenn Sie eine Sammlung von Zeichenfolgen direkt sortieren möchten, müssen Sie die ursprüngliche Sammlung sortieren, in der IEnumerable <string> implementiert ist, oder zuerst IEnumerable <string> in eine sortierbare Sammlung umwandeln:

List<string> myList = myEnumerable.ToList();
myList.Sort();

Basierend auf Ihrem Kommentar:

_components = (from c in xml.Descendants("component")
               let value = (string)c
               orderby value
               select value
              )
              .Distinct()
              .ToList();

oder

_components = xml.Descendants("component")
                 .Select(c => (string)c)
                 .Distinct()
                 .OrderBy(v => v)
                 .ToList();

oder (wenn Sie der Liste später weitere Elemente hinzufügen und sie sortiert lassen möchten)

_components = xml.Descendants("component")
                 .Select(c => (string)c)
                 .Distinct()
                 .ToList();

_components.Add("foo");
_components.Sort();
140
dtb

Es ist unmöglich, aber es ist nicht möglich.

Grundsätzlich wird jede Sortiermethode Ihre IEnumerable in eine List kopieren, die List sortieren und dann die sortierte Liste, die eine IEnumerable ist, an Sie zurückgeben. ] sowie ein IList.

Dies bedeutet, dass Sie die Eigenschaft "unendlich weitermachen" eines IEnumerable verlieren, aber dann können Sie sowieso keine solche sortieren.

9
James Curran
myEnumerable = myEnumerable.OrderBy(s => s);
8
Larsenal

Wir können dies nicht immer vor Ort tun, aber wir erkennen, wann es möglich ist:

IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src, IComparer<T> cmp)
{
  List<T> listToSort = (src is List<T>) ? (List<T>)src : new List<T>(src);
  listToSort.Sort(cmp);
  return listToSort;
}
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src, Comparison<T> cmp)
{
  return SortInPlaceIfCan(src, new FuncComparer<T>(cmp));
}
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src)
{
  return SortInPlaceIfCan(src, Comparer<T>.Default);
}

Dies verwendet die folgende handliche Struktur:

internal struct FuncComparer<T> : IComparer<T>
{
  private readonly Comparison<T> _cmp;
  public FuncComparer(Comparison<T> cmp)
  {
      _cmp = cmp;
  }
  public int Compare(T x, T y)
  {
      return _cmp(x, y);
  }
}
2
Jon Hanna