Risposte:
Nello stesso modo in cui ordineresti qualsiasi altro enumerabile:
var result = myEnumerable.OrderBy(s => s);
o
var result = from s in myEnumerable
orderby s
select s;
o (ignorando maiuscole e minuscole)
var result = myEnumerable.OrderBy(s => s,
StringComparer.CurrentCultureIgnoreCase);
Si noti che, come al solito con LINQ, questo crea un nuovo IEnumerable <T> che, quando enumerato, restituisce gli elementi dell'originale IEnumerable <T> in ordine ordinato. Non ordina IEnumerable <T> sul posto.
Un IEnumerable <T> è di sola lettura, ovvero è possibile solo recuperare gli elementi da esso, ma non modificarlo direttamente. Se si desidera ordinare una raccolta di stringhe sul posto, è necessario ordinare la raccolta originale che implementa IEnumerable <string> o prima trasformare un IEnumerable <string> in una raccolta ordinabile:
List<string> myList = myEnumerable.ToList();
myList.Sort();
In base al tuo commento:
_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();
oppure (se desideri aggiungere in seguito più elementi all'elenco e mantenerlo ordinato)
_components = xml.Descendants("component")
.Select(c => (string)c)
.Distinct()
.ToList();
_components.Add("foo");
_components.Sort();
OrderBy
ritorna IOrderedEnumerable<T>
. IOrderedEnumerable<T>
deriva da IEnumerable<T>
quindi può essere utilizzato come IEnumerable<T>
, ma ne estende la tipologia, consentendo ad esempio l'utilizzo di ThenBy
.
È impossibile, ma non lo è.
Fondamentalmente, qualsiasi metodo di ordinamento copierà il tuo IEnumerable
in un List
, ordina il List
e poi ti restituisce l'elenco ordinato, che è IEnumerable
un file IList
.
Ciò significa che perdi la proprietà "continua infinitamente" di un IEnumerable
, ma non puoi comunque ordinarne uno in quel modo.
Non possiamo sempre farlo sul posto, ma rileviamo quando è possibile:
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);
}
Questo usa la seguente pratica struttura:
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);
}
}
listToSort = (src is List<T>) ? (List<T>)src : new List<T>(src);
? Che ne dici di averlo comelistToSort = (src as List<T>); if (null == listToSort) listToSort = new List<T>(src);