List<T>.Sort() / Reverse() / ForEach()
| 対応: | C# 2.0(2005) |
|---|
リストを並べ替える『Sort()』、要素の順序を逆にする『Reverse()』、すべての要素にアクションを実行する『ForEach()』メソッドです。
構文
using System.Collections.Generic; // リストをデフォルトの順序で昇順に並べ替えます(元のリストを変更します) list.Sort() // ラムダ式で比較条件を指定して並べ替えます list.Sort(Comparison<T> comparison) // リストの要素の順序を逆にします(元のリストを変更します) list.Reverse() // すべての要素に対してアクションを実行します list.ForEach(Action<T> action)
メソッド一覧
| メソッド | 概要 |
|---|---|
| Sort() | リストの要素をデフォルトの比較方法で昇順に並べ替えます。元のリストが変更されます。 |
| Sort(Comparison<T> comparison) | ラムダ式などの比較関数を指定して並べ替えます。 |
| Reverse() | リスト全体の要素の並びを逆順にします。元のリストが変更されます。 |
| ForEach(Action<T> action) | 各要素に対してアクション(処理)を実行します。foreach 文と同等ですが、ラムダ式でシンプルに書けます。 |
サンプルコード
Sort() で昇順に並べ替え、Reverse() で降順にします。ForEach() でラムダ式を使って全要素を処理します。
Program.cs
using System;
using System.Collections.Generic;
List<int> scores = new List<int> { 78, 92, 45, 88, 61 };
scores.Sort();
Console.WriteLine(string.Join(", ", scores)); // 45, 61, 78, 88, 92
scores.Reverse();
Console.WriteLine(string.Join(", ", scores)); // 92, 88, 78, 61, 45
scores.ForEach(p => Console.Write(p + " "));
Console.WriteLine();
dotnet run 45, 61, 78, 88, 92 92, 88, 78, 61, 45 92 88 78 61 45
カスタム条件での並べ替え
Sort() にラムダ式を渡すと、任意の比較条件で並べ替えられます。戻り値が負のとき a が先、正のとき b が先になります。CompareTo() を使うと簡潔に書けます。
CustomSortSample.cs
using System;
using System.Collections.Generic;
List<string> names = new List<string> { "岡部倫太郎", "椎名まゆり", "牧瀬紅莉栖", "橋田至" };
names.Sort((a, b) => a.Length.CompareTo(b.Length));
names.ForEach(n => Console.WriteLine(n));
dotnet run 橋田至 岡部倫太郎 椎名まゆり 牧瀬紅莉栖
同じ文字数の要素の並びは環境によって異なる場合があります。List.Sort() は安定ソートを保証しません。
元のリストを保持してから並べ替える
Sort() と Reverse() は元のリストを直接変更します。元の並びを保持したい場合は、あらかじめ new List<T>() でコピーを作成してから並べ替えます。
PreserveSample.cs
using System;
using System.Collections.Generic;
List<int> original = new List<int> { 3, 1, 4, 1, 5, 9 };
List<int> sorted = new List<int>(original);
sorted.Sort();
Console.WriteLine(string.Join(", ", original)); // 3, 1, 4, 1, 5, 9(変更なし)
Console.WriteLine(string.Join(", ", sorted)); // 1, 1, 3, 4, 5, 9
dotnet run 3, 1, 4, 1, 5, 9 1, 1, 3, 4, 5, 9
よくあるミス
よくあるミス: ForEach() 内で break や continue は使えない
ForEach() のラムダ式の中では break や continue が使えません。途中で処理を中断したい場合は通常の foreach 文を使ってください。
using System;
using System.Collections.Generic;
// NG: ForEach() 内で break は使えない(コンパイルエラー)
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// numbers.ForEach(n => {
// if (n == 3) break; // CS0139: 囲んでいるループまたはスイッチの外に break を置くことはできません
// Console.WriteLine(n);
// });
修正後は次の通りです。
using System;
using System.Collections.Generic;
// OK: 通常の foreach 文を使う
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
foreach (int n in numbers)
{
if (n == 3) break;
Console.WriteLine(n);
}
dotnet run 1 2
概要
Sort() と Reverse() はどちらも元のリストを直接変更します。元のリストを保持したい場合は、あらかじめ new List<T>(元のリスト) でコピーを作成してから操作してください。
ForEach() はラムダ式を使って foreach をシンプルに書けますが、ループ中で break や continue は使えません。途中で処理を中断したい場合は通常の foreach 文を使ってください。
リストへの追加・削除には『List<T>.Add() / Remove() / Clear()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。