コレクション内の要素の存在確認
C#で配列やリストを扱う際、「このリストの中に特定の値が含まれているか?」を確認したい場面は頻繁にあります。例えば、入力されたIDが許可リストにあるか、あるいは指定された数値が当たり番号に含まれているか、といったケースです。
foreachループで回して一つずつ比較することも可能ですが、C#のLINQ(Language Integrated Query)が提供するContainsメソッドを使用することで、この判定処理を非常にシンプルに記述できます。
この記事では、Containsメソッドの基本的な使い方から、文字列の大文字・小文字を無視した判定方法、そしてパフォーマンスに関する注意点について解説します。
Contains メソッドの基本
Containsメソッドは、引数で指定した値がシーケンス(配列やリストなど)の中に存在する場合に true を、存在しない場合に false を返します。
コード例1:数値の存在チェック
宝くじの当選番号リスト(整数の配列)の中に、ユーザーが持っている番号が含まれているかを確認する例です。
using System;
using System.Linq; // LINQを使用するために必須
public class ContainsNumberExample
{
public static void Main()
{
// 当選番号のリスト
int[] winningNumbers = { 1024, 2056, 3301, 4500, 5120 };
int userNumber = 3301;
int invalidNumber = 9999;
// Contains で判定
bool isWinner = winningNumbers.Contains(userNumber);
bool isLoser = winningNumbers.Contains(invalidNumber);
Console.WriteLine($"番号 {userNumber} は当選か: {isWinner}");
Console.WriteLine($"番号 {invalidNumber} は当選か: {isLoser}");
}
}
出力結果:
番号 3301 は当選か: True
番号 9999 は当選か: False
応用:文字列の大文字・小文字を無視してチェック
string型のコレクションに対してContainsを使用する場合、デフォルトでは大文字と小文字が厳密に区別されます。
もし、「.jpg」と「.JPG」を同じとみなして判定したい場合は、Containsメソッドの第2引数に IEqualityComparer<T> を指定できるオーバーロードを使用します。文字列の場合は StringComparer クラスを利用するのが便利です。
コード例2:ファイル拡張子の許可チェック
アップロードされたファイルの拡張子が、許可リスト(小文字で定義)に含まれているかを、大文字・小文字を無視して判定する例です。
using System;
using System.Linq;
using System.Collections.Generic;
public class ContainsStringExample
{
public static void Main()
{
// 許可されている拡張子リスト
var allowedExtensions = new List<string> { ".jpg", ".png", ".gif" };
// ユーザーが指定した拡張子(大文字)
string inputExtension = ".PNG";
// 1. 通常の Contains (大文字・小文字を区別する)
// ".PNG" はリストにないので false
bool basicCheck = allowedExtensions.Contains(inputExtension);
Console.WriteLine($"通常のチェック (.PNG): {basicCheck}");
// 2. StringComparer を指定した Contains (大文字・小文字を無視)
// OrdinalIgnoreCase を指定することで true になる
bool ignoreCaseCheck = allowedExtensions.Contains(
inputExtension,
StringComparer.OrdinalIgnoreCase
);
Console.WriteLine($"文字種無視チェック (.PNG): {ignoreCaseCheck}");
}
}
出力結果:
通常のチェック (.PNG): False
文字種無視チェック (.PNG): True
パフォーマンスとコレクションの選択
Containsメソッドは便利ですが、使用するコレクションの型によってパフォーマンス(検索速度)が大きく異なります。
List<T>や 配列 (T[]) の場合: **線形探索(O(n))**が行われます。リストの先頭から順番に探していくため、要素数が増えると検索にかかる時間も比例して長くなります。データ量が数千件を超える場合や、頻繁に検索を行う場合は注意が必要です。HashSet<T>の場合: **ハッシュ探索(O(1))**が行われます。要素数が多くても、ほぼ一瞬で判定が完了します。
大量のデータを検索する場合の最適解
もし、検索対象のリストが巨大で、かつ何度もContainsを呼び出す必要がある場合は、List<T>のままではなく、一度HashSet<T>に変換してから検索することを推奨します。
// 検索対象が大量にある場合
var largeDataList = GetHugeData(); // List<int>
// HashSet に変換して検索を高速化
var searchSet = new HashSet<int>(largeDataList);
if (searchSet.Contains(targetValue)) // 非常に高速
{
// ...
}
まとめ
Containsメソッドは、コレクション内の要素の有無を調べるための最も基本的なメソッドです。
- 基本:
collection.Contains(value)で存在判定ができます。 - 文字列:
StringComparerを渡すことで、大文字・小文字を無視した判定が可能です。 - パフォーマンス: 要素数が多い場合は、
List<T>ではなくHashSet<T>の使用を検討することで、処理速度を大幅に向上させることができます。
