IT

C# リストで複数キーを指定したソート方法


システムオペレーション部のS666です。
 
あるプロジェクトで複数項目からなるListをランキング形式で出力したいとの話がありました。
リストの項目(1)が降順、項目(2)が昇順、項目(3)が昇順にしてほしいとのこと。。。
 
調べてみると、IOrderedEnumerableというインターフェイスがありました。
 
今回の「項目(1)が降順、項目(2)が昇順、項目(3)が昇順」を例にするとこのように記述ができます。
 

    class Program
    {
        static void Main(string[] args)
        {
            List<Test1> list = new List<Test1>(new Test1[] {
                new Test1(0, "b", 3, 1),
                new Test1(1, "d", 1, 2),
                new Test1(0, "a", 2, 3),
                new Test1(1, "c", 2, 4),
                new Test1(0, "e", 1, 5),
            });

            // Flagを降順、strIDを昇順、IDを昇順として並べ替える
            IOrderedEnumerable<Test1> sortList =
                list.OrderByDescending(rec => rec.Flag).ThenBy(rec => rec.strID).ThenBy(rec => rec.ID);

            foreach (Test1 rec in sortList)
            {
                Console.WriteLine("{0},{1},{2},{3}", rec.Flag, rec.strID, rec.ID, rec.Rank);
            }
        }
    }

    class Test1
    {
        public int Flag;
        public int ID;
        public string strID;
        public int Rank;

        public Test1(int flag, string strId, int id, int rank)
        {
            this.Flag = flag;
            this.ID = id;
            this.strID = strId;
            this.Rank = rank;
        }
    }

 
使用したメソッドを調べるとこのようになっています。
 

OrderBy シーケンスの要素をキーに従って昇順に並べ替えます。
OrderByDescending シーケンスの要素をキーに従って降順に並べ替えます。
ThenBy キーに従って昇順のシーケンス内の要素の後続の並べ替えを実行します。
ThenByDescending キーに従って降順に並べ替え、シーケンス内の要素の後続の並べ替えを実行します。

 
ちなみに「項目(1)が昇順、項目(2)が降順、項目(3)が降順」の場合はこのような記述です。
 

            // Flagを昇順、strIDを降順、IDを降順として並べ替える
            IOrderedEnumerable<Test1> sortList =
            list.OrderBy(rec => rec.Flag).ThenByDescending(rec => rec.strID).ThenByDescending(rec => rec.ID);

 
なお、これらは遅延実行されるため、戻り値(今回の場合はsortList)に対してforeach等で列挙操作を行うまではソートされないそうです。
 
みなさん、ご参考にいかがでしょうか。