How to sort an IEnumerable<string>
Solution 1:
The same way you'd sort any other enumerable:
var result = myEnumerable.OrderBy(s => s);
or
var result = from s in myEnumerable
orderby s
select s;
or (ignoring case)
var result = myEnumerable.OrderBy(s => s,
StringComparer.CurrentCultureIgnoreCase);
Note that, as is usual with LINQ, this creates a new IEnumerable<T> which, when enumerated, returns the elements of the original IEnumerable<T> in sorted order. It does not sort the IEnumerable<T> in-place.
An IEnumerable<T> is read-only, that is, you can only retrieve the elements from it, but cannot modify it directly. If you want to sort a collection of strings in-place, you need to sort the original collection which implements IEnumerable<string>, or turn an IEnumerable<string> into a sortable collection first:
List<string> myList = myEnumerable.ToList();
myList.Sort();
Based on your comment:
_components = (from c in xml.Descendants("component")
let value = (string)c
orderby value
select value
)
.Distinct()
.ToList();
or
_components = xml.Descendants("component")
.Select(c => (string)c)
.Distinct()
.OrderBy(v => v)
.ToList();
or (if you want to later add more items to the list and keep it sorted)
_components = xml.Descendants("component")
.Select(c => (string)c)
.Distinct()
.ToList();
_components.Add("foo");
_components.Sort();
Solution 2:
It is impossible, but it isn't.
Basically, any sort method is going to copy your IEnumerable
into a List
, sort the List
and then return to you the sorted list, which is an IEnumerable
as well as an IList
.
This means you lose the "continue infinitely" property of an IEnumerable
, but then you couldn't sort one like that anyway.
Solution 3:
myEnumerable = myEnumerable.OrderBy(s => s);
Solution 4:
We can't always do it in-place, but we detect when it's possible:
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);
}
This uses the following handy struct:
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);
}
}