C# の LINQ で条件判定する Any と All
Any と All はシーケンスに対する条件判定を行うメソッドだ。どちらも bool を返し、存在確認や全体チェックに使う。
Any:存在確認
条件を満たす要素が1つでもあれば true を返す。
int[] numbers = { 1, 2, 3, 4, 5 };
bool hasEven = numbers.Any(n => n % 2 == 0);
Console.WriteLine(hasEven); // True偶数が存在するかどうかを確認している。見つかった時点で探索を終了するので、大きなコレクションでも効率的だ。
引数なしの Any() は、要素が1つでもあれば true を返す。
var empty = new List<int>();
var notEmpty = new List<int> { 1, 2, 3 };
Console.WriteLine(empty.Any()); // False
Console.WriteLine(notEmpty.Any()); // True空のコレクションかどうかを判定するのに便利だ。Count() > 0 より高速で、意図も明確になる。
All:全体確認
すべての要素が条件を満たす場合に true を返す。
int[] numbers = { 2, 4, 6, 8, 10 };
bool allEven = numbers.All(n => n % 2 == 0);
Console.WriteLine(allEven); // Trueすべての数が偶数かどうかを確認している。条件を満たさない要素が見つかった時点で探索を終了し、false を返す。
int[] numbers = { 2, 4, 5, 8, 10 };
bool allEven = numbers.All(n => n % 2 == 0);
Console.WriteLine(allEven); // False(5は奇数)空のコレクションに注意
空のコレクションに対する All は true を返す。これは「条件を満たさない要素が存在しない」という論理に基づく。
var empty = new List<int>();
bool result = empty.All(n => n > 100);
Console.WriteLine(result); // True(空なので)直感に反するかもしれないが、数学的には「空集合に対する全称命題は真」という原則に従っている。必要であれば Any() と組み合わせてチェックする。
var list = new List<int>();
// 空でなく、かつすべてが正の数
bool allPositive = list.Any() && list.All(n => n > 0);Any と All の関係
論理的には、Any と All は否定で関連している。
!numbers.Any(条件)
条件を満たす要素が1つもない
numbers.All(!条件)
すべての要素が条件を満たさない
どちらで書いても同じ結果になるが、可読性を考慮して適切な方を選ぶべきだ。
int[] numbers = { 1, 3, 5, 7, 9 };
// どちらも同じ意味
bool noEven1 = !numbers.Any(n => n % 2 == 0);
bool noEven2 = numbers.All(n => n % 2 != 0);
Console.WriteLine(noEven1); // True
Console.WriteLine(noEven2); // True実用的な例
ユーザー入力のバリデーション
var inputs = new List<string> { "Alice", "Bob", "Charlie" };
// 空文字やnullが含まれていないか
bool isValid = inputs.All(s => !string.IsNullOrEmpty(s));権限チェック
var userPermissions = new List<string> { "read", "write" };
var requiredPermissions = new List<string> { "read", "write", "delete" };
// 必要な権限をすべて持っているか
bool hasAllPermissions = requiredPermissions.All(
required => userPermissions.Contains(required)
);
Console.WriteLine(hasAllPermissions); // False(deleteがない)在庫確認
var products = new List<Product>
{
new Product { Name = "A", Stock = 10 },
new Product { Name = "B", Stock = 0 },
new Product { Name = "C", Stock = 5 }
};
// 在庫切れの商品があるか
bool hasOutOfStock = products.Any(p => p.Stock == 0);
Console.WriteLine(hasOutOfStock); // Trueパフォーマンスの利点
Any と All は条件が決定した時点で探索を終了する(短絡評価)。
var numbers = Enumerable.Range(1, 1000000);
// 最初の要素で即座に true を返す
bool hasPositive = numbers.Any(n => n > 0);
// 最初の要素で即座に false を返す
bool allNegative = numbers.All(n => n < 0);100万件のデータでも、条件によっては最初の数件で結果が確定する。Where(...).Count() > 0 のような書き方に比べて効率的だ。
Contains との違い
特定の値の存在確認には Contains を使うこともできる。
int[] numbers = { 1, 2, 3, 4, 5 };
// どちらも同じ意味
bool has3_any = numbers.Any(n => n == 3);
bool has3_contains = numbers.Contains(3);単純な値の存在確認なら Contains の方が簡潔だ。複雑な条件には Any を使う。