C# で複数のプロパティの値でリストをソートする方法

C# で複数のプロパティの値でリストをソートする

クラスのオブジェクトのリスト (List) があって、オブジェクトの複数のプロパティの値でソートしたリストを取得したい時ありませんか?

例えば、次のような Student クラスのリスト List<Student> があって、ClassCode、LastName、FirstName でソートしたリストを取得したいような時です。

class Student
{
    public int StudentID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Gender { get; set; }
    public string ClassCode { get; set; }

    public Student(int studentID, string firstName, string lastName, string gender, string classCode)
    {
        StudentID = studentID;
        FirstName = firstName;
        LastName = lastName;
        Gender = gender;
        ClassCode = classCode;
    }
}

C# でリストを複数のプロパティの値で昇順にソートしたリストを取得したいい時には、LinqOrderBy メソッドと ThenBy メソッドが使えます。

ひとつめのプロパティには OrderBy を使い、それ以降のプロパティには ThenBy を使います。

例えば、プロパティ1、プロパティ2、プロパティ3 の順番で昇順にソートしたい時は次のようにします。

リスト.OrderBy(obj => obj.プロパティ1).ThenBy(obj => obj.プロパティ2).ThenBy(obj => obj.プロパティ3).ToList()

obj としている箇所は他の名前でも大丈夫です。

Linq の OrderBy や ThenBy は IOrderedEnumerable を返すので、ToList メソッドで List に変換しています。


降順にソートしたい時は代わりに LinqOrderByDescending メソッドや ThenByDescending メソッドを使います。

使い方は OrderBy や ThenBy と同じです。


C# で students リストを ClassCode、LastName、FirstName でソートしたリストを取得サンプルーコードは次の通りです。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ListTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var students = new List();
            students.Add(new Student(1, "Kana", "Yamada", "F", "ClassC"));
            students.Add(new Student(2, "Keita", "Maeda", "M", "ClassC"));
            students.Add(new Student(3, "Kaede", "Tanaka", "F", "ClassA"));
            students.Add(new Student(4, "Ryota", "Suzuki", "M", "ClassB"));
            students.Add(new Student(5, "Yuri", "Nakata", "F", "ClassB"));
            students.Add(new Student(5, "Misaki", "Nakata", "F", "ClassB"));
            students.Add(new Student(5, "Mana", "Yamamoto", "F", "ClassA"));

            foreach(var s in students)
            {
                Console.WriteLine(s.ClassCode + ": " + s.LastName + ", " + s.FirstName);
            }

            Console.WriteLine("-------------------");

            var students2 = students.OrderBy(s => s.ClassCode).ThenBy(s => s.LastName).ThenBy(s => s.FirstName).ToList();

            foreach (var s in students2)
            {
                Console.WriteLine(s.ClassCode + ": " + s.LastName + ", " + s.FirstName);
            }

            Console.WriteLine("-------------------");

            var students3 = students.OrderByDescending(s => s.ClassCode).ThenBy(s => s.LastName).ThenByDescending(s => s.FirstName).ToList();

            foreach (var s in students3)
            {
                Console.WriteLine(s.ClassCode + ": " + s.LastName + ", " + s.FirstName);
            }
        }
    }

    class Student
    {
        public int StudentID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Gender { get; set; }
        public string ClassCode { get; set; }

        public Student(int studentID, string firstName, string lastName, string gender, string classCode)
        {
            StudentID = studentID;
            FirstName = firstName;
            LastName = lastName;
            Gender = gender;
            ClassCode = classCode;
        }
    }
}

11 ~ 18 行目では Student クラスのオブジェクトを持つ List を生成しています。

27 行目では、Linq の OrderBy と ThenBy メソッドを使って、students リストを ClassCode、LastName、FirstName の昇順にソートしたオブジェクトを持つ List<Student> を生成しています。

36 行目では、Linq の OrderByDescending と ThenByDescending メソッドも使って、students リストを ClassCode 降順、LastName 昇順、FirstName 降順にソートしたオブジェクトを持つ List<Student> を生成しています。


上のコードを実行すると次のようになります。

ClassC: Yamada, Kana
ClassC: Maeda, Keita
ClassA: Tanaka, Kaede
ClassB: Suzuki, Ryota
ClassB: Nakata, Yuri
ClassB: Nakata, Misaki
ClassA: Yamamoto, Mana
-------------------
ClassA: Tanaka, Kaede
ClassA: Yamamoto, Mana
ClassB: Nakata, Misaki
ClassB: Nakata, Yuri
ClassB: Suzuki, Ryota
ClassC: Maeda, Keita
ClassC: Yamada, Kana
-------------------
ClassC: Maeda, Keita
ClassC: Yamada, Kana
ClassB: Nakata, Yuri
ClassB: Nakata, Misaki
ClassB: Suzuki, Ryota
ClassA: Tanaka, Kaede
ClassA: Yamamoto, Mana
Press any key to continue . . .

C# で複数のプロパティの値でリストをソートする方法 1


新しくできた List の中の Student オブジェクトは、元のリストと同じ Student オブジェクトをポイントしているので、クラス変数の値を変更すると、全てのリストに入っている同じ Student オブジェクトの値が変更されます。


以上、C# で複数のプロパティの値でリストをソートする方法をご紹介しました。

© 2024 C# 入門