开发者

How to sort an IEnumerable<string>

How can 开发者_开发百科I sort an IEnumerable<string> alphabetically. Is this possible?

Edit: How would I write an in-place solution?


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


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.


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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜