C#の配列でContainsを使う方法|要素の存在確認をLINQ・Listとの違いまで解説
はじめに
C#で配列の中に特定の値が含まれているか確認したい場合、よく使われるのがContainsです。
たとえば、次のような場面で役立ちます。
C#int[] numbers = { 1, 2, 3, 4, 5 };
bool result = numbers.Contains(3);
このコードでは、numbers配列の中に3が含まれているかを判定しています。結果はtrueになります。
C#の配列でContainsを使うと、数値や文字列などの要素が配列内に存在するかを簡単に確認できます。ただし、配列のContainsはLINQの拡張メソッドであるため、using System.Linq;が必要です。
この記事では、C#の配列でContainsを使う基本的な書き方から、ListのContainsとの違い、部分一致検索、エラーの原因、パフォーマンス面の注意点まで解説します。
1. C#の配列でContainsを使う基本
1-1. Containsとは何か
Containsは、コレクションの中に指定した要素が含まれているかを調べるためのメソッドです。
C#では、配列やList、HashSetなどのデータ構造に対して、特定の値が存在するかを確認したい場面がよくあります。
たとえば、次のような確認です。
C#int[] numbers = { 10, 20, 30 };
bool hasValue = numbers.Contains(20);
この場合、配列numbersの中に20があるため、hasValueにはtrueが入ります。
1-2. 配列の中に指定した要素があるか確認する仕組み
配列でContainsを使うと、配列の先頭から順番に要素を確認し、指定した値と一致するものがあるかを調べます。
C#string[] fruits = { "apple", "banana", "orange" };
bool result = fruits.Contains("banana");
このコードでは、配列の中に"banana"が存在するため、resultはtrueになります。
一方、存在しない値を指定した場合はfalseになります。
C#bool result = fruits.Contains("grape");
"grape"は配列に含まれていないため、結果はfalseです。
1-3. Containsを使うために必要なusing System.Linq
C#の配列でContainsを使うには、基本的にファイルの先頭でSystem.Linqを読み込む必要があります。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains(2);
Console.WriteLine(result);
}
}
配列そのものにContainsというインスタンスメソッドが直接定義されているわけではありません。配列に対して使うContainsは、LINQが提供する拡張メソッドです。
そのため、using System.Linq;を書き忘れると、環境によっては次のようなエラーになります。
C#'int[]' does not contain a definition for 'Contains'
1-4. Containsの戻り値はbool型
Containsの戻り値はbool型です。
指定した要素が含まれていればtrue、含まれていなければfalseを返します。
C#int[] numbers = { 1, 2, 3 };
bool exists = numbers.Contains(3);
Console.WriteLine(exists); // true
bool型で返ってくるため、if文と組み合わせて使うことが多いです。
C#if (numbers.Contains(3))
{
Console.WriteLine("3が含まれています");
}
2. C#の配列でContainsを使う書き方
2-1. int配列で数値の存在を確認する例
まずは、int配列で数値が含まれているか確認する基本例です。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
int[] numbers = { 10, 20, 30, 40, 50 };
bool result = numbers.Contains(30);
Console.WriteLine(result);
}
}
実行結果は次のようになります。
C#true
30は配列の中に存在するため、Contains(30)はtrueを返します。
存在しない数値を指定するとfalseになります。
C#bool result = numbers.Contains(100);
Console.WriteLine(result); // false
2-2. string配列で文字列の存在を確認する例
文字列配列でも同じようにContainsを使えます。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
string[] languages = { "C#", "Java", "Python", "JavaScript" };
bool result = languages.Contains("C#");
Console.WriteLine(result);
}
}
実行結果は次のとおりです。
C#true
"C#"が配列に含まれているため、結果はtrueになります。
ただし、文字列の場合は大文字・小文字が区別されます。
C#bool result = languages.Contains("c#");
Console.WriteLine(result); // false
配列には"C#"はありますが、"c#"はないためfalseになります。
2-3. if文と組み合わせて条件分岐する方法
Containsはif文と組み合わせることで、要素が存在する場合だけ処理を実行できます。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
string[] roles = { "Admin", "User", "Guest" };
string currentRole = "Admin";
if (roles.Contains(currentRole))
{
Console.WriteLine("有効なロールです");
}
else
{
Console.WriteLine("無効なロールです");
}
}
}
この例では、currentRoleの値がroles配列に含まれているかを判定しています。
"Admin"は配列に含まれているため、次のように表示されます。
C#有効なロールです
2-4. 否定条件で「含まれていない」を判定する方法
配列に値が含まれていないことを判定したい場合は、!を使って否定します。
C#int[] numbers = { 1, 2, 3, 4, 5 };
if (!numbers.Contains(10))
{
Console.WriteLine("10は含まれていません");
}
Contains(10)はfalseを返しますが、!によって結果が反転するため、条件式はtrueになります。
文字列配列でも同じです。
C#string[] bannedWords = { "spam", "danger", "ng" };
string input = "hello";
if (!bannedWords.Contains(input))
{
Console.WriteLine("禁止ワードではありません");
}
3. Containsが使えない・エラーになる原因
3-1. System.Linqを読み込んでいない
配列でContainsが使えない原因として最も多いのが、using System.Linq;を書いていないケースです。
次のコードはエラーになる可能性があります。
C#using System;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains(2);
}
}
配列に対するContainsはLINQの拡張メソッドなので、次のようにSystem.Linqを追加します。
C#using System;
using System.Linq;
これでnumbers.Contains(2)を使えるようになります。
3-2. 型が一致していない
Containsでは、配列の要素の型と検索する値の型が一致している必要があります。
C#int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains("1");
このコードでは、numbersはint[]ですが、Containsに渡している値は文字列の"1"です。そのため、型が一致せずエラーになります。
正しくは次のように書きます。
C#bool result = numbers.Contains(1);
文字列として判定したい場合は、最初からstring[]を使います。
C#string[] numbers = { "1", "2", "3" };
bool result = numbers.Contains("1");
3-3. nullを含む配列で注意すべきこと
string配列などの参照型配列では、要素にnullが含まれる場合があります。
C#string[] names = { "Alice", null, "Bob" };
bool result = names.Contains(null);
Console.WriteLine(result); // true
Contains(null)自体は可能です。配列内にnullが含まれていればtrueになります。
ただし、配列の各要素に対してメソッドを呼び出す場合は注意が必要です。
C#string[] names = { "Alice", null, "Bob" };
bool result = names.Any(name => name.Contains("A"));
このコードでは、nameがnullのときにname.Contains("A")を呼び出すため、NullReferenceExceptionが発生します。
安全に書くには、次のようにnullチェックを入れます。
C#bool result = names.Any(name => name != null && name.Contains("A"));
または、null条件演算子を使う方法もあります。
C#bool result = names.Any(name => name?.Contains("A") == true);
3-4. 古いC#環境や.NET環境で確認すべき点
Containsを配列に対して使う場合、LINQが使える環境である必要があります。
通常の.NET Framework、.NET Core、.NET 5以降、.NET 6以降などでは問題なく使えますが、古い.NET Framework環境ではLINQが使えない場合があります。
特に.NET Framework 2.0などの古い環境では、LINQのEnumerable.Containsが使えません。その場合は、Array.IndexOfやforeach文で代用できます。
C#int[] numbers = { 1, 2, 3 };
bool exists = Array.IndexOf(numbers, 2) >= 0;
LINQが使えない環境では、このような書き方を検討しましょう。
4. 文字列配列でContainsを使うときの注意点
4-1. 大文字・小文字は区別される
文字列配列でContainsを使う場合、標準では大文字・小文字が区別されます。
C#string[] languages = { "C#", "Java", "Python" };
Console.WriteLine(languages.Contains("C#")); // true
Console.WriteLine(languages.Contains("c#")); // false
"C#"と"c#"は別の文字列として扱われます。
ユーザー入力を判定する場合など、大文字・小文字の違いを無視したいケースでは注意が必要です。
4-2. 完全一致で判定される
配列に対するContainsは、要素全体が一致するかどうかを判定します。
C#string[] words = { "apple", "banana", "orange" };
bool result = words.Contains("app");
Console.WriteLine(result); // false
"apple"の中に"app"は含まれていますが、配列の要素として"app"が存在するわけではありません。そのため、結果はfalseになります。
つまり、配列のContainsは部分一致ではなく完全一致の判定です。
4-3. 部分一致で検索したい場合はAnyを使う
文字列配列の中から、特定の文字列を含む要素を探したい場合は、Anyと文字列のContainsを組み合わせます。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
string[] words = { "apple", "banana", "orange" };
bool result = words.Any(word => word.Contains("app"));
Console.WriteLine(result);
}
}
実行結果は次のようになります。
C#true
このコードでは、配列内の各要素に対してword.Contains("app")を実行しています。
"apple"が"app"を含んでいるため、結果はtrueになります。
配列そのもののContainsと、文字列のContainsは意味が異なる点に注意しましょう。
C#words.Contains("app"); // 配列の要素として"app"があるか
words.Any(word => word.Contains("app")); // 各文字列の中に"app"を含むものがあるか
4-4. 大文字・小文字を無視して判定する方法
大文字・小文字を無視して完全一致を判定したい場合は、Containsのオーバーロードに比較方法を指定します。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
string[] languages = { "C#", "Java", "Python" };
bool result = languages.Contains("c#", StringComparer.OrdinalIgnoreCase);
Console.WriteLine(result);
}
}
実行結果は次のようになります。
C#true
StringComparer.OrdinalIgnoreCaseを指定することで、"C#"と"c#"を同じ文字列として扱えます。
部分一致で大文字・小文字を無視したい場合は、次のように書けます。
C#string[] words = { "Apple", "Banana", "Orange" };
bool result = words.Any(word =>
word.Contains("app", StringComparison.OrdinalIgnoreCase));
古い.NET環境でstring.ContainsにStringComparisonを指定できない場合は、IndexOfを使う方法があります。
C#bool result = words.Any(word =>
word.IndexOf("app", StringComparison.OrdinalIgnoreCase) >= 0);
5. 配列のContainsとListのContainsの違い
5-1. 配列で使うContainsはLINQの拡張メソッド
C#の配列で使うContainsは、LINQが提供する拡張メソッドです。
C#using System.Linq;
int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains(2);
配列型であるint[]自体にContainsメソッドが定義されているわけではありません。
System.Linqを読み込むことで、Enumerable.Containsを配列に対して呼び出せるようになります。
5-2. ListのContainsはListクラスのメソッド
一方、List<T>にはContainsメソッドが最初から用意されています。
C#using System.Collections.Generic;
List<int> numbers = new List<int> { 1, 2, 3 };
bool result = numbers.Contains(2);
List<T>のContainsは、List<T>クラスに定義されているメソッドです。
そのため、単純にListのContainsを使うだけであれば、System.Linqは必須ではありません。
5-3. 書き方の違い
配列の場合は次のように書きます。
C#using System.Linq;
int[] array = { 1, 2, 3 };
bool result = array.Contains(2);
Listの場合は次のように書きます。
C#using System.Collections.Generic;
List<int> list = new List<int> { 1, 2, 3 };
bool result = list.Contains(2);
どちらも見た目は似ていますが、内部的には呼び出しているメソッドが異なります。
配列ではLINQの拡張メソッド、ListではList<T>のインスタンスメソッドです。
5-4. 使い分けの目安
配列とListは、用途に応じて使い分けます。
要素数が固定で、追加や削除をほとんど行わない場合は配列が向いています。
C#string[] roles = { "Admin", "User", "Guest" };
一方、要素を後から追加・削除したい場合はListが便利です。
C#List<string> roles = new List<string>();
roles.Add("Admin");
roles.Add("User");
Containsだけで見ると、どちらも同じように存在確認ができます。ただし、データを柔軟に変更する必要があるならList、固定的なデータを扱うなら配列を選ぶとよいでしょう。
6. Contains以外で配列の要素を検索する方法
6-1. Array.Existsを使う方法
Array.Existsを使うと、条件に一致する要素が配列に存在するかを確認できます。
C#int[] numbers = { 1, 2, 3, 4, 5 };
bool result = Array.Exists(numbers, n => n > 3);
Console.WriteLine(result); // true
Array.Existsは、単純な値の一致だけでなく、条件式を使った検索ができます。
C#string[] names = { "Alice", "Bob", "Charlie" };
bool result = Array.Exists(names, name => name.StartsWith("A"));
この例では、"A"で始まる名前が存在するかを確認しています。
6-2. Array.IndexOfを使う方法
Array.IndexOfは、指定した要素が配列の何番目にあるかを返します。
C#int[] numbers = { 10, 20, 30 };
int index = Array.IndexOf(numbers, 20);
Console.WriteLine(index); // 1
配列のインデックスは0から始まるため、20はインデックス1にあります。
存在しない場合は-1が返ります。
C#int index = Array.IndexOf(numbers, 100);
Console.WriteLine(index); // -1
存在確認だけをしたい場合は、次のように書けます。
C#bool exists = Array.IndexOf(numbers, 20) >= 0;
6-3. Anyを使う方法
LINQのAnyを使うと、条件に一致する要素が1つでもあるかを判定できます。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
bool result = numbers.Any(n => n % 2 == 0);
Console.WriteLine(result);
}
}
このコードでは、偶数が1つでも含まれているかを確認しています。
2や4があるため、結果はtrueです。
Containsは指定した値と一致するかを調べるときに便利ですが、条件付きで検索したい場合はAnyが適しています。
6-4. FindやFindIndexとの違い
Array.Findは、条件に一致する最初の要素を取得します。
C#int[] numbers = { 1, 2, 3, 4, 5 };
int found = Array.Find(numbers, n => n > 3);
Console.WriteLine(found); // 4
Array.FindIndexは、条件に一致する最初の要素のインデックスを取得します。
C#int index = Array.FindIndex(numbers, n => n > 3);
Console.WriteLine(index); // 3
それぞれの使い分けは次のようになります。
C#numbers.Contains(3); // 値が存在するか確認
Array.Exists(numbers, n => n > 3); // 条件に一致する要素があるか確認
Array.IndexOf(numbers, 3); // 値のインデックスを取得
Array.Find(numbers, n => n > 3); // 条件に一致する要素を取得
Array.FindIndex(numbers, n => n > 3); // 条件に一致するインデックスを取得
存在確認だけならContainsやExists、要素そのものを取得したいならFind、位置を知りたいならIndexOfやFindIndexを使うとよいでしょう。
7. Containsを使うときの実践的なケース
7-1. 入力値が許可リストに含まれるか確認する
ユーザーの入力値が許可された値かどうかを判定する場合、Containsが便利です。
C#using System;
using System.Linq;
class Program
{
static void Main()
{
string[] allowedRoles = { "Admin", "Editor", "Viewer" };
string inputRole = "Editor";
if (allowedRoles.Contains(inputRole))
{
Console.WriteLine("許可されたロールです");
}
else
{
Console.WriteLine("許可されていないロールです");
}
}
}
このように、許可リストを配列で定義し、その中に入力値が含まれているかを確認できます。
ユーザー権限、カテゴリ、ステータスなどの判定によく使われます。
7-2. 禁止ワードを判定する
禁止ワードの完全一致判定にもContainsを使えます。
C#string[] bannedWords = { "spam", "ngword", "danger" };
string input = "spam";
if (bannedWords.Contains(input))
{
Console.WriteLine("禁止ワードです");
}
この例では、入力値が禁止ワード配列に含まれていれば警告を表示します。
ただし、文章の中に禁止ワードが含まれるかを調べたい場合は、配列のContainsではなくAnyを使います。
C#string[] bannedWords = { "spam", "ngword", "danger" };
string message = "this is spam message";
bool hasBannedWord = bannedWords.Any(word => message.Contains(word));
if (hasBannedWord)
{
Console.WriteLine("禁止ワードが含まれています");
}
このように、完全一致なのか部分一致なのかによって書き方を変える必要があります。
7-3. 複数のIDやコードの存在確認をする
複数のIDやコードの中から、対象の値が含まれているかを確認する場合にもContainsは便利です。
C#int[] targetIds = { 101, 102, 103, 104 };
int userId = 103;
if (targetIds.Contains(userId))
{
Console.WriteLine("対象ユーザーです");
}
文字列のコードにも使えます。
C#string[] validCodes = { "A001", "B002", "C003" };
string code = "B002";
if (validCodes.Contains(code))
{
Console.WriteLine("有効なコードです");
}
このような処理は、商品コード、ユーザーID、カテゴリコード、ステータスコードなどのチェックでよく使われます。
7-4. enumや定数配列と組み合わせる
enumの値を配列にして、特定の値が許可されているか確認することもできます。
C#using System;
using System.Linq;
enum OrderStatus
{
New,
Paid,
Shipped,
Cancelled
}
class Program
{
static void Main()
{
OrderStatus[] editableStatuses =
{
OrderStatus.New,
OrderStatus.Paid
};
OrderStatus currentStatus = OrderStatus.New;
if (editableStatuses.Contains(currentStatus))
{
Console.WriteLine("編集可能なステータスです");
}
}
}
このように、業務ルールを配列として定義しておくと、条件分岐が読みやすくなります。
複雑なif文を何度も書くより、許可リストや対象リストを配列にまとめてContainsで判定した方が、コードの意図が伝わりやすくなります。
8. Containsのパフォーマンスと注意点
8-1. 配列のContainsは先頭から順番に検索する
配列に対するContainsは、基本的に先頭から順番に要素を確認します。
C#int[] numbers = { 1, 2, 3, 4, 5 };
bool result = numbers.Contains(5);
この場合、5を見つけるために、1、2、3、4、5と順番に確認します。
要素数が少ない配列であれば問題になることはほとんどありません。しかし、要素数が非常に多い配列で何度も検索する場合は、処理速度に注意が必要です。
8-2. 要素数が多い場合はHashSetを検討する
大量のデータに対して存在確認を何度も行う場合は、HashSet<T>の利用を検討するとよいでしょう。
C#using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
HashSet<int> ids = new HashSet<int> { 101, 102, 103, 104 };
bool result = ids.Contains(103);
Console.WriteLine(result);
}
}
HashSet<T>は、要素の存在確認を高速に行いやすいデータ構造です。
配列のContainsは先頭から順番に探すのに対して、HashSet<T>は検索に向いた構造を持っています。
ただし、HashSet<T>は重複要素を保持できない点に注意が必要です。
C#HashSet<int> numbers = new HashSet<int> { 1, 1, 2, 3 };
Console.WriteLine(numbers.Count); // 3
重複を意味のあるデータとして扱いたい場合は、配列やListの方が適しています。
8-3. 繰り返し検索する場合の最適化
配列に対して1回だけContainsを使う程度であれば、過度にパフォーマンスを気にする必要はありません。
C#int[] ids = { 1, 2, 3, 4, 5 };
bool exists = ids.Contains(3);
しかし、ループの中で何度もContainsを実行する場合は注意が必要です。
C#int[] allowedIds = { 1, 2, 3, 4, 5 };
foreach (int id in manyIds)
{
if (allowedIds.Contains(id))
{
Console.WriteLine(id);
}
}
manyIdsの件数が多い場合、毎回allowedIdsを先頭から検索することになります。
このような場合は、事前にHashSet<T>へ変換しておくと効率的です。
C#HashSet<int> allowedIdSet = new HashSet<int>(allowedIds);
foreach (int id in manyIds)
{
if (allowedIdSet.Contains(id))
{
Console.WriteLine(id);
}
}
繰り返し検索する場合は、配列のまま検索するより、検索用のデータ構造を用意した方がよいケースがあります。
8-4. 可読性と処理速度のバランス
Containsは非常に読みやすい書き方です。
C#if (roles.Contains(currentRole))
{
Console.WriteLine("許可されています");
}
このコードは、「rolesの中にcurrentRoleが含まれているか」を直感的に理解できます。
要素数が少なく、検索回数も少ない場合は、配列のContainsで十分です。
一方で、数万件以上のデータを何度も検索する場合は、HashSet<T>や辞書型の利用を検討した方がよいでしょう。
大切なのは、最初から過剰に最適化することではなく、データ量や処理回数に応じて適切な方法を選ぶことです。
9. オブジェクト配列でContainsを使う方法
9-1. クラスの配列でContainsを使う場合の注意点
Containsは、クラスの配列に対しても使えます。
C#using System;
using System.Linq;
class User
{
public int Id { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main()
{
User user1 = new User { Id = 1, Name = "Alice" };
User user2 = new User { Id = 2, Name = "Bob" };
User[] users = { user1, user2 };
bool result = users.Contains(user1);
Console.WriteLine(result);
}
}
この場合、user1は配列に入っている同じインスタンスなので、結果はtrueになります。
しかし、次のコードでは結果が異なります。
C#User[] users =
{
new User { Id = 1, Name = "Alice" },
new User { Id = 2, Name = "Bob" }
};
User target = new User { Id = 1, Name = "Alice" };
bool result = users.Contains(target);
Console.WriteLine(result); // false
IdやNameの値は同じですが、別のインスタンスであるため、標準ではfalseになります。
9-2. 参照比較と値比較の違い
クラスは参照型です。
そのため、Equalsを特別に実装していない場合、Containsでは基本的に同じ参照かどうかが比較されます。
C#User a = new User { Id = 1, Name = "Alice" };
User b = new User { Id = 1, Name = "Alice" };
Console.WriteLine(a == b); // false
aとbは同じ値を持っていますが、別々に作成されたオブジェクトなので、参照は異なります。
値の内容で比較したい場合は、Equalsをオーバーライドするか、Anyで条件を指定して検索します。
9-3. Equalsをオーバーライドする方法
オブジェクトの値でContainsを判定したい場合は、クラスでEqualsとGetHashCodeをオーバーライドします。
C#using System;
using System.Linq;
class User
{
public int Id { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
if (obj is not User other)
{
return false;
}
return Id == other.Id && Name == other.Name;
}
public override int GetHashCode()
{
return HashCode.Combine(Id, Name);
}
}
class Program
{
static void Main()
{
User[] users =
{
new User { Id = 1, Name = "Alice" },
new User { Id = 2, Name = "Bob" }
};
User target = new User { Id = 1, Name = "Alice" };
bool result = users.Contains(target);
Console.WriteLine(result); // true
}
}
このようにEqualsをオーバーライドすると、Containsはオブジェクトの値をもとに比較できます。
ただし、クラス全体の等価性のルールに影響するため、慎重に設計する必要があります。
9-4. 条件付き検索にはAnyを使う
オブジェクト配列では、特定のプロパティを条件にして検索したいことがよくあります。
その場合は、ContainsよりもAnyの方が適しています。
C#User[] users =
{
new User { Id = 1, Name = "Alice" },
new User { Id = 2, Name = "Bob" }
};
bool result = users.Any(user => user.Id == 1);
Console.WriteLine(result); // true
名前で検索する場合は次のように書けます。
C#bool result = users.Any(user => user.Name == "Alice");
複数条件も指定できます。
C#bool result = users.Any(user => user.Id == 1 && user.Name == "Alice");
オブジェクト配列では、単純に同じインスタンスが含まれているかを調べるならContains、プロパティの条件で検索するならAnyを使うと分かりやすくなります。
10. C#の配列Containsに関するよくある質問
10-1. 配列にContainsメソッドは本当にあるのか
C#の配列そのものに、Containsというインスタンスメソッドが直接定義されているわけではありません。
配列で使うContainsは、LINQの拡張メソッドです。
そのため、次のようにSystem.Linqを読み込む必要があります。
C#using System.Linq;
すると、次のように配列に対してContainsを呼び出せます。
C#int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains(2);
見た目としては配列のメソッドのように使えますが、実際にはLINQの機能によって使えるようになっています。
10-2. Containsで部分一致検索はできるのか
配列のContainsでは、部分一致検索はできません。
C#string[] words = { "apple", "banana", "orange" };
bool result = words.Contains("app");
Console.WriteLine(result); // false
このコードは、配列の要素として"app"が存在するかを調べています。"apple"の中に"app"が含まれていても、完全一致ではないためfalseになります。
部分一致検索をしたい場合は、Anyと文字列のContainsを組み合わせます。
C#bool result = words.Any(word => word.Contains("app"));
Console.WriteLine(result); // true
10-3. 複数条件で要素を検索するにはどうするのか
複数条件で検索したい場合は、ContainsよりもAnyを使うのが一般的です。
C#User[] users =
{
new User { Id = 1, Name = "Alice" },
new User { Id = 2, Name = "Bob" },
new User { Id = 3, Name = "Alice" }
};
bool result = users.Any(user => user.Id == 3 && user.Name == "Alice");
このコードでは、Idが3かつNameが"Alice"のユーザーが存在するかを判定しています。
単純な値の存在確認ならContains、条件を指定した検索ならAnyと考えると分かりやすいです。
10-4. ContainsとAnyはどちらを使うべきか
指定した値が配列に含まれているかを確認するだけなら、Containsを使うのがおすすめです。
C#int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains(2);
この書き方はシンプルで読みやすく、意図も明確です。
一方、条件を指定して検索したい場合はAnyを使います。
C#bool result = numbers.Any(n => n > 2);
文字列の部分一致検索でもAnyを使います。
C#string[] words = { "apple", "banana", "orange" };
bool result = words.Any(word => word.Contains("app"));
使い分けの目安は次のとおりです。
C#array.Contains(value); // 指定した値があるか
array.Any(x => 条件); // 条件に一致する要素があるか
単純な完全一致ならContains、柔軟な条件検索ならAnyを選びましょう。
まとめ
C#の配列で要素の存在確認をしたい場合は、Containsを使うと簡潔に書けます。
C#int[] numbers = { 1, 2, 3 };
bool result = numbers.Contains(2);
配列のContainsを使うには、基本的にusing System.Linq;が必要です。
C#using System.Linq;
Containsは、指定した値が配列に含まれていればtrue、含まれていなければfalseを返します。そのため、if文と組み合わせることで、条件分岐を分かりやすく書けます。
C#if (numbers.Contains(2))
{
Console.WriteLine("含まれています");
}
ただし、文字列配列で使う場合は、大文字・小文字が区別されること、部分一致ではなく完全一致で判定されることに注意が必要です。
部分一致検索をしたい場合は、Anyと文字列のContainsを組み合わせます。
C#string[] words = { "apple", "banana", "orange" };
bool result = words.Any(word => word.Contains("app"));
また、配列のContainsは先頭から順番に検索するため、大量のデータを何度も検索する場合はHashSet<T>の利用も検討しましょう。
C#HashSet<int> ids = new HashSet<int> { 1, 2, 3 };
bool result = ids.Contains(2);
C#の配列でContainsを使うと、コードを短く読みやすくできます。単純な存在確認にはContains、条件付き検索にはAny、位置を知りたい場合はArray.IndexOfやFindIndexを使い分けると、より分かりやすく保守しやすいコードになります。

