C# の LINQ で並べ替える OrderBy
OrderBy はシーケンスの要素を昇順に並べ替えるメソッドだ。降順にしたい場合は OrderByDescending を使う。
基本的な使い方
数値を昇順で並べ替える。
int[] numbers = { 5, 2, 8, 1, 9, 3 };
var sorted = numbers.OrderBy(n => n);
foreach (var n in sorted)
{
Console.Write($"{n} "); // 1 2 3 5 8 9
}ラムダ式でソートのキーを指定する。この例では要素そのものをキーにしている。
降順に並べ替える
OrderByDescending を使えば降順になる。
int[] numbers = { 5, 2, 8, 1, 9, 3 };
var sorted = numbers.OrderByDescending(n => n);
foreach (var n in sorted)
{
Console.Write($"{n} "); // 9 8 5 3 2 1
}メソッド名が変わるだけで、使い方は同じだ。
オブジェクトの並べ替え
プロパティをキーにして並べ替えることが多い。
var people = new List<Person>
{
new Person { Name = "Charlie", Age = 35 },
new Person { Name = "Alice", Age = 25 },
new Person { Name = "Bob", Age = 30 }
};
// 年齢で昇順
var byAge = people.OrderBy(p => p.Age);
foreach (var person in byAge)
{
Console.WriteLine($"{person.Name}: {person.Age}");
}
// Alice: 25
// Bob: 30
// Charlie: 35年齢をキーにして並べ替えている。名前で並べ替えたければ p => p.Name とすればいい。
複数条件での並べ替え
ThenBy や ThenByDescending を使えば、第二、第三のソートキーを指定できる。
var people = new List<Person>
{
new Person { Name = "Alice", Age = 25, City = "Tokyo" },
new Person { Name = "Bob", Age = 30, City = "Osaka" },
new Person { Name = "Charlie", Age = 25, City = "Tokyo" },
new Person { Name = "Diana", Age = 30, City = "Tokyo" }
};
// 年齢で昇順、同じ年齢なら名前で昇順
var sorted = people
.OrderBy(p => p.Age)
.ThenBy(p => p.Name);
foreach (var person in sorted)
{
Console.WriteLine($"{person.Name}: {person.Age}");
}
// Alice: 25
// Charlie: 25
// Bob: 30
// Diana: 30最初に年齢で並べ、年齢が同じ場合は名前のアルファベット順になる。
OrderBy + ThenBy
第一キーで昇順、第二キーで昇順
OrderBy + ThenByDescending
第一キーで昇順、第二キーで降順
OrderByDescending + ThenBy
第一キーで降順、第二キーで昇順
文字列の並べ替え
文字列はデフォルトで辞書順(アルファベット順)に並ぶ。
string[] fruits = { "banana", "Apple", "cherry", "apricot" };
var sorted = fruits.OrderBy(f => f);
foreach (var fruit in sorted)
{
Console.WriteLine(fruit);
}
// Apple, apricot, banana, cherry注意点として、大文字は小文字より前に来る(ASCII 順)。大文字小文字を区別せずに並べたい場合は、StringComparer を指定する。
string[] fruits = { "banana", "Apple", "cherry", "apricot" };
var sorted = fruits.OrderBy(f => f, StringComparer.OrdinalIgnoreCase);
foreach (var fruit in sorted)
{
Console.WriteLine(fruit);
}
// Apple, apricot, banana, cherrynull の扱い
ソートキーに null が含まれる場合、null は最小値として扱われ、昇順では先頭に来る。
var people = new List<Person>
{
new Person { Name = "Bob" },
new Person { Name = null },
new Person { Name = "Alice" }
};
var sorted = people.OrderBy(p => p.Name);
foreach (var person in sorted)
{
Console.WriteLine(person.Name ?? "(null)");
}
// (null)
// Alice
// Bobnull を最後に持っていきたい場合は、カスタムロジックを使う必要がある。
安定ソート
LINQ の OrderBy は安定ソート(stable sort)だ。同じキー値を持つ要素は、元の順序が維持される。
var items = new List<(string Name, int Priority)>
{
("A", 1),
("B", 2),
("C", 1),
("D", 2)
};
var sorted = items.OrderBy(x => x.Priority);
foreach (var item in sorted)
{
Console.WriteLine($"{item.Name}: {item.Priority}");
}
// A: 1 (元は1番目)
// C: 1 (元は3番目)
// B: 2 (元は2番目)
// D: 2 (元は4番目)同じ Priority を持つ A と C、B と D は、元の登場順が保たれている。これは複数条件でソートする際に重要な性質となる。