Pregunta Cómo ordenar un IEnumerable


¿Cómo puedo ordenar una IEnumerable<string> alfabéticamente. es posible?

Editar: ¿Cómo escribiría una solución in situ?


74
2017-09-02 19:51


origen


Respuestas:


De la misma manera que ordenarías cualquier otro enumerable:

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

o

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

o (ignorando el estuche)

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

Tenga en cuenta que, como es habitual con LINQ, esto crea un nuevo IEnumerable <T> que, cuando se enumera, devuelve los elementos del IEnumerable <T> original en orden ordenado. No ordena el IEnumerable <T> in situ.


Un IEnumerable <T> es de solo lectura, es decir, solo puede recuperar los elementos de él, pero no puede modificarlo directamente. Si desea ordenar una colección de cadenas en el lugar, debe ordenar la colección original que implementa IEnumerable <cadena> o convertir una IEnumerable <cadena> en una colección ordenable primero:

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

En base a tu comentario:

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

o

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

o (si luego desea agregar más elementos a la lista y mantenerlos ordenados)

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

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

126
2017-09-02 19:52



Es imposible, pero no lo es.

Básicamente, cualquier método de clasificación va a copiar tu IEnumerable en un List, ordena el List y luego devolvemos la lista ordenada, que es una IEnumerable así como también IList.

Esto significa que pierde la propiedad "continuar infinitamente" de un IEnumerable, pero entonces no podrías ordenar uno así de todos modos.


9
2017-09-02 19:57



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

8
2017-09-02 20:06



No siempre podemos hacerlo en el lugar, pero detectamos cuándo es posible:

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

Esto usa la siguiente estructura útil:

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
2017-09-02 20:49