Come ordinare un IEnumerable<string>
in ordine alfabetico. È possibile?Come ordinare un oggetto IEnumerable <string>
Modifica: come scrivere una soluzione sul posto?
Come ordinare un IEnumerable<string>
in ordine alfabetico. È possibile?Come ordinare un oggetto IEnumerable <string>
Modifica: come scrivere una soluzione sul posto?
Lo stesso modo che ci ordinare qualsiasi altro enumerabile:
var result = myEnumerable.OrderBy(s => s);
o
var result = from s in myEnumerable
orderby s
select s;
o (caso ignorando)
var result = myEnumerable.OrderBy(s => s,
StringComparer.CurrentCultureIgnoreCase);
Nota che, come al solito con LINQ , questo crea un nuovo IEnumerable <T> che, quando enumerato, restituisce gli elementi di l'originale IEnumerable <T> in ordine ordinato. Non ordina l'IEnumerable <T> sul posto.
un IEnumerable <T> è di sola lettura, cioè, è possibile recuperare solo gli elementi da esso, ma non può modificare direttamente. Se si desidera ordinare una collezione di stringhe in-luogo, è necessario risolvere la collezione originale che implementa IEnumerable <stringa>, o girare un < stringa IEnumerable > in una collezione ordinabile prima:
List<string> myList = myEnumerable.ToList();
myList.Sort();
sulla base della sua 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();
o (se si desidera aggiungere in seguito altri elementi alla lista e tenerlo allineati)
_components = xml.Descendants("component")
.Select(c => (string)c)
.Distinct()
.ToList();
_components.Add("foo");
_components.Sort();
E 'impossibile, ma non lo è.
In sostanza, qualsiasi metodo di ordinamento sta per copiare il IEnumerable
in un List
, ordinare la List
e poi tornare a voi la lista ordinata, che è un IEnumerable
così come un IList
.
Ciò significa che si perde la proprietà "continua all'infinito" di uno IEnumerable
, ma in questo caso non è possibile selezionarne uno simile.
Esatto. Lo scopo di IEnumerable è quello di presentarti un handle per una serie che puoi iterare, dall'inizio alla fine, continuando a chiedere l'elemento "next". Ciò significa che un oggetto IEnumerable può essere parzialmente iterato prima che tutti i contenuti siano conosciuti; non devi sapere quando li hai attraversati tutti fino a quando non l'hai fatto. L'ordinamento (come molte cose che Linq consente di fare) richiede la conoscenza dell'intera serie come una lista ordinata; l'elemento che appare per primo in una serie ordinata potrebbe essere l'ultimo restituito da una serie e non lo saprai a meno che tu non sappia cosa sono tutti gli articoli. – KeithS
myEnumerable = myEnumerable.OrderBy(s => s);
Non possiamo sempre farlo sul posto, ma noi di rilevare 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 utilizza la seguente struct a portata di mano:
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);
}
}
Non sono sicuro se lo consiglierei. Se possiedi un oggetto IEnumerable
Nel modificare ciò che abbiamo, ho preso ciò che è implicito nella domanda in cerca di posto; che lo sottintende. È un motivo per avere "InPlaceInCan" nel nome del metodo; i nomi dei metodi possono essere ancora più precoci sui rischi rispetto alla migliore documentazione;) Sì, Array.FunctorComparer
@dtb su ripensamenti, cambiato per usare il mio (dai un'occhiata a Array.FunctorComparer di nuovo e preferisco il mio comunque!) –
o myEnumerable.OrderByDescending (s => s). – Grozz
+1, potrebbe includere ignorare il caso. – user7116
Quindi, _components = _components.OrderBy (s => s); andrebbe bene? – CatZilla