web-dev-qa-db-ja.com

IEnumerable <string>を並べ替える方法

IEnumerable<string>をアルファベット順に並べ替えるにはどうすればよいですか。これは可能ですか?

編集:どのようにインプレースソリューションを作成しますか?

87
CatZilla

他の列挙可能なものをソートするのと同じ方法:

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 <T>を作成し、列挙されると、元のIEnumerable <T>の要素をソートされた順序で返すことに注意してください。 IEnumerable <T>をその場で並べ替えません。


IEnumerable <T>は読み取り専用です。つまり、そこから要素のみを取得できますが、直接変更することはできません。文字列のコレクションをインプレースで並べ替える場合は、IEnumerable <string>を実装する元のコレクションを並べ替えるか、最初にIEnumerable <string>を並べ替え可能なコレクションに変換する必要があります。

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

それは不可能ですが、不可能ではありません。

基本的に、どのソート方法でもIEnumerableListにコピーし、Listをソートしてから、ソートされたリスト(IEnumerableおよびIList)に戻ります。

これは、IEnumerableの「無限に継続」プロパティを失うことを意味しますが、そのようなものはとにかくソートできませんでした。

9
James Curran
myEnumerable = myEnumerable.OrderBy(s => s);
8
Larsenal

常にインプレースで実行できるとは限りませんが、可能な場合は検出します。

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);
  }
}
2
Jon Hanna