C#の複数のフィールドでオブジェクトのリストを並べ替える
この投稿では、C#の複数のフィールドに対してオブジェクトのリストを並べ替える方法について説明します。
1.LINQの使用
リストの並べ替えられたコピーを作成するには、LINQを使用できます OrderBy() 方法。オブジェクトを後続のフィールドと比較するには、 ThenBy() メソッド(または ThenByDescending
).
たとえば、次のコードは、最初に従業員のリストを name
フィールドそしてそれから age
フィールド、つまり、同じ名前の従業員の場合、従業員の年齢によって順序が決まります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
using System; using System.Linq; using System.Collections.Generic; public class Person { public string name; public int age; public Person(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Person tom27 = new Person("Tom", 27); Person roger21 = new Person("Roger", 21); Person fred24 = new Person("Fred", 24); Person fred30 = new Person("Fred", 30); List<Person> people = new List<Person>() { tom27, roger21, fred24, fred30 }; List<Person> sorted = people.OrderBy(x => x.name) .ThenBy(x => x.age) .ToList(); Console.WriteLine(String.Join(Environment.NewLine, sorted)); } } /* 出力: [Fred,24] [Fred,30] [Roger,21] [Tom,27] */ |
2.使用する List<T>.Sort
方法 (System.Collections.Generic
)
上記のLINQソリューションは、リストの新しいソート済みコピーを作成します。推奨されるアプローチは、リストを使用することです Sort() リストをソートする方法 所定の位置に.ソートを行うことができます Comparison<T>
代理人または IComparer<T>
/IComparable<T> implementation.
1.使用できます 比較代表 自然な順序を持たないオブジェクトに順序を提供します。並べ替えメソッドに渡すと、要素の並べ替え順序を正確に制御できます。比較デリゲートは、を使用して実装できます ラムダ式。のリストを比較するには Employee
最初のオブジェクト name
そして age
、 我々はできる:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
using System; using System.Linq; using System.Collections.Generic; public class Person { public string name; public int age; public Person(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Person tom27 = new Person("Tom", 27); Person roger21 = new Person("Roger", 21); Person fred24 = new Person("Fred", 24); Person fred30 = new Person("Fred", 30); List<Person> people = new List<Person>() { tom27, roger21, fred24, fred30 }; people.Sort((x, y) => { int ret = String.Compare(x.name, y.name); return ret != 0 ? ret : x.age.CompareTo(y.age); }); Console.WriteLine(String.Join(Environment.NewLine, people)); } } /* 出力: [Fred,24] [Fred,30] [Roger,21] [Tom,27] */ |
2.別のアプローチは、カスタムを提供することです IComparer<T> を使用してリストを分別するための実装 Sort()
方法。アイデアは、 IComparer<T>
別のクラスのインターフェイス、そのオーバーライド Compare()
メソッド、およびそのクラスのインスタンスをに渡します Sort()
方法。比較するフィールドが複数ある場合、これはラムダ式への推奨されるアプローチです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
using System; using System.Collections.Generic; public class PersonComparer: IComparer<Person> { public int Compare(Person x, Person y) { if (object.ReferenceEquals(x, y)) { return 0; } if (x == null) { return -1; } if (y == null) { return 1; } int ret = String.Compare(x.name, y.name); return ret != 0 ? ret : x.age.CompareTo(y.age); } } public class Person { public string name; public int age; public Person(string name, int age) { this.name = name; this.age = age; } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Person tom27 = new Person("Tom", 27); Person roger21 = new Person("Roger", 21); Person fred24 = new Person("Fred", 24); Person fred30 = new Person("Fred", 30); List<Person> people = new List<Person>() { tom27, roger21, fred24, fred30 }; people.Sort(new PersonComparer()); Console.WriteLine(String.Join(Environment.NewLine, people)); } } /* 出力: [Fred,24] [Fred,30] [Roger,21] [Tom,27] */ |
3. IComparable<T> インターフェイスは、それを実装する各クラスのオブジェクトに自然な順序を課します。次のコードでは、 Employee
クラスは IComparable<T>
インターフェイスとそのオーバーライド CompareTo()
方法。 The List
の Employee
次に、オブジェクトは引数なしを使用してソートされます Sort()
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
using System; using System.Collections.Generic; public class Person: IComparable<Person> { public string name; public int age; public Person(string name, int age) { this.name = name; this.age = age; } public int CompareTo(Person emp) { if (emp == null) { return 1; } int ret = String.Compare(this.name, emp.name); return ret != 0 ? ret : this.age.CompareTo(emp.age); } public override string ToString() { return "[" + name + "," + age + "]"; } } public class Example { public static void Main() { Person tom27 = new Person("Tom", 27); Person roger21 = new Person("Roger", 21); Person fred24 = new Person("Fred", 24); Person fred30 = new Person("Fred", 30); List<Person> people = new List<Person>() { tom27, roger21, fred24, fred30 }; people.Sort(); Console.WriteLine(String.Join(Environment.NewLine, people)); } } /* 出力: [Fred,24] [Fred,30] [Roger,21] [Tom,27] */ |
これで、C#の複数のフィールドでオブジェクトのリストを分別ることができます。