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# でリストを複数のプロパティの値で昇順にソートしたリストを取得したいい時には、Linq の OrderBy メソッドと 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 に変換しています。
降順にソートしたい時は代わりに Linq の OrderByDescending メソッドや 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 . . .
新しくできた List の中の Student オブジェクトは、元のリストと同じ Student オブジェクトをポイントしているので、クラス変数の値を変更すると、全てのリストに入っている同じ Student オブジェクトの値が変更されます。
以上、C# で複数のプロパティの値でリストをソートする方法をご紹介しました。