IEnumerable<string>
をアルファベット順に並べ替えるにはどうすればよいですか。これは可能ですか?
編集:どのようにインプレースソリューションを作成しますか?
他の列挙可能なものをソートするのと同じ方法:
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();
それは不可能ですが、不可能ではありません。
基本的に、どのソート方法でも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);
}
}