OrderBy及びOrderByDescendingは、ともに並び替えを行うクエリ演算子です。
SQLでもおなじみのものなので、あまり説明することがありませんw
OrderBy及びOrderByDescendingメソッドは、単一キーでのソートを行います。
複合キーでのソートを行う場合には、次回記述するThenBy, ThenByDescendingを
組み合わせて利用します。
書式は以下のようになっています。
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector ) public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer ) public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector ) public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer )
どちらも2つずつ定義されていて、片方はIComparer
カスタムオブジェクトを作成していて、そのComparerが存在する場合に利用します。
一点だけ、注目するべき所は、戻り値です。
通常のクエリ演算子では、IEnumerable
IOrderedEnumerable
戻り値がこのようになっているのは理由があって、次回取り上げるThenBy, ThenByDescendingにつなげるように
なっているためです。ThenBy, ThenByDescendingメソッドは、共にIOrderedEnumerable
定義されています。なので、必然的にThenBy, ThenByDescendingはOrderByの後で利用しないといけないようになっています。
尚、LINQのソートは、「安定ソート (Stable Sort)」です。
以下サンプルです。
#region LinqSamples-22 public class LinqSamples22 : IExecutable { class Person { public int Id { get; set; } public string Name { get; set; } public override string ToString() { return string.Format("[ID={0}, NAME={1}]", Id, Name); } } public void Execute() { var persons = new List<Person> { new Person{ Id = 1001, Name = "gsf_zero1" }, new Person{ Id = 1000, Name = "gsf_zero2" }, new Person{ Id = 111, Name = "gsf_zero3" }, new Person{ Id = 9889, Name = "gsf_zero4" }, new Person{ Id = 9889, Name = "gsf_zero5" }, new Person{ Id = 100, Name = "gsf_zero6" } }; // // 順序付け演算子には、以下のものが存在する。 // // ・OrderBy // ・OrderByDescending // ・ThenBy // ・ThenByDescending // // OrderByは昇順ソート、OrderByDescendingは降順ソートを行う。どちらも単一キーにてソートを行う。 // 複合キーにて、ソート処理を行う場合は、OrderBy及びOrderByDescendingに続いて、ThenBy及びThenByDescendingを利用する。 // // OrderBy及びOrderByDescendingメソッドは、他のLINQ標準演算子と戻り値が異なっており // IOrderedEnumerable<T> // を返す。また、ThenBy及びThenByDescendingメソッドは、引数にIOrderedEnumerable<T>を渡す必要がある。 // なので、必然的に、ThenByはOrderByの後で呼び出さないと利用出来ない。 // // LINQの並び替え処理は、安定ソート(Stable Sort)である。 // つまり、同じキーの要素がシーケンス内に複数存在した場合、並び替えた結果は元の順番を保持している。 // // // IDで昇順ソート. // var sortByIdAsc = persons.OrderBy(aPerson => aPerson.Id); Console.WriteLine("================= IDで昇順ソート ================="); Console.WriteLine(string.Join(Environment.NewLine, sortByIdAsc)); // // IDで降順ソート. // var sortByIdDesc = persons.OrderByDescending(aPerson => aPerson.Id); Console.WriteLine("================= IDで降順ソート ================="); Console.WriteLine(string.Join(Environment.NewLine, sortByIdDesc)); // // 安定ソートの確認。 // var sortByIdAscAndDesc = persons.OrderByDescending(aPerson => aPerson.Id).OrderBy(aPerson => aPerson.Id); Console.WriteLine("================= 安定ソートの確認 ================="); Console.WriteLine(string.Join(Environment.NewLine, sortByIdAscAndDesc)); } } #endregion
実行すると以下のように出力されます。
================= IDで昇順ソート ================= [ID=100, NAME=gsf_zero6] [ID=111, NAME=gsf_zero3] [ID=1000, NAME=gsf_zero2] [ID=1001, NAME=gsf_zero1] [ID=9889, NAME=gsf_zero4] [ID=9889, NAME=gsf_zero5] ================= IDで降順ソート ================= [ID=9889, NAME=gsf_zero4] [ID=9889, NAME=gsf_zero5] [ID=1001, NAME=gsf_zero1] [ID=1000, NAME=gsf_zero2] [ID=111, NAME=gsf_zero3] [ID=100, NAME=gsf_zero6] ================= 安定ソートの確認 ================= [ID=100, NAME=gsf_zero6] [ID=111, NAME=gsf_zero3] [ID=1000, NAME=gsf_zero2] [ID=1001, NAME=gsf_zero1] [ID=9889, NAME=gsf_zero4] [ID=9889, NAME=gsf_zero5]
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ