Как сортировать интерфейс IEnumerable



Как я могу отсортировать IEnumerable<string> в алфавитном порядке. Это возможно?



Edit: как бы я написал решение на месте?

734   4  

4 ответов:

так же, как вы бы любого другого перечислимого:

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

или

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

или (игнорируя регистр)

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

обратите внимание, что, как обычно с LINQ, это создает новый IEnumerable, который при перечислении возвращает элементы исходного IEnumerable в отсортированном порядке. Он не сортирует IEnumerable на месте.


IEnumerable доступен только для чтения, то есть вы можете только извлекать элементы из него, но не можете изменять это напрямую. Если вы хотите отсортировать коллекцию строк на месте, вам нужно сначала отсортировать исходную коллекцию, которая реализует IEnumerable, или превратить IEnumerable в сортируемую коллекцию:

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

на основе вашего комментария:

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

или

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

или (если вы хотите позже добавить несколько товаров в список хранить)

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

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

это невозможно, но это не так.

в принципе, любой метод сортировки будет копировать ваш IEnumerable на List и List а затем вернуть вам отсортированного списка, который является IEnumerable и IList.

это означает, что вы теряете свойство "продолжать бесконечно"IEnumerable, но тогда вы не могли бы что-то подобное.

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

мы не всегда можем сделать это на месте, но мы обнаруживаем, когда это возможно:

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

при этом используется следующая удобная структура:

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

Comments

    Ничего не найдено.