【ソースコード有】C#のforeachの使い方は?配列での使用方法を解説
ここではループ処理には欠かせないforeach文の構造や特徴、記述方法などについて、実際のコードを元にくわしく解説していきます。
ここではループ処理には欠かせないforeach文の構造や特徴、記述方法などについて、実際のコードを元にくわしく解説していきます。
スキルアップ
2023/02/22 UP
- プログラミング
- SE資格・スキル
- C#
foreach文は、for文のように繰り返しループ処理を行う構文で、for文と比較すると簡潔な記述が可能です。配列やDictionaryなどのコレクションの要素にアクセスする場合に使用し、すべての要素を1回ずつ読み出すことができます。また、配列のように要素の列挙ができないコレクションでも使用が可能です。
ここではループ処理には欠かせないforeach文の構造や特徴、記述方法などについて、実際のコードを元にくわしく解説していきます。
なお、C#について環境構築から知りたいかたは、こちらの記事も併せてご確認ください。
C#の入門者が覚えておきたい機能の特徴や開発環境の構築方法
foreach文とは?
foreach文はループ処理を行う構文の一種です。配列、List、Dictionaryなどが有するコレクションにアクセスし、要素を取り出すことができます。for文より簡潔に記述でき、可読性が高いことから、ループ処理で起きやすいトラブルを軽減し、バグの発生を減らすメリットがあります。
一方で、foreach文とfor文のどちらを使う方が処理が速いかは、データ構造によって変わります。そのため、両方のループ処理を理解した上で、状況に応じた使い分けが大切です。
foreach文とfor文の違い
foreach文は、インデックス番号を指定するint型変数iを定義したり、ループごとにインクリメント(i++)したりする必要がありません。実際に構文の基本型を比較してみましょう。
foreach文の基本型:
foreach(型名 オブジェクト名 in コレクション) {
処理文
}
for文の基本型:
for(int i = 0; i < コレクションの要素数; i++) {
処理文
}
for文がint型変数iを定義して、ループ処理ごとにインクリメントしているのに対し、foreach文では型名とオブジェクト名の定義だけになっており、コレクションの要素数を取得していません。
foreach文の書き方
実際に使用するforeach文の書き方を解説していきます。サンプルコードを元に、基本的なforeach文の書き方を学んでみましょう。
サンプルコードをVisual Studioに貼り付けて実行すると、foreach文の挙動がよりわかりやすいので、練習用のコンソールアプリを作成し、実行しながら学習を進めてください。
1次元配列
1次元配列は、1行だけで構成された配列です。サンプルコードでは、numbersという名前で宣言した1次元配列に対して、foreach文を用いて配列の左から順に要素にアクセスし、Console.WriteLineを使って、取得した内容をコンソール画面に列挙しています。
サンプルコード:
class Sample
{
public static void Main()
{
// 配列の宣言
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6 };
foreach (int num in numbers)
{
// 画面に出力
Console.WriteLine("{0}", num);
}
}
}
このサンプルコードを実行すると、以下の画面のようになります。
多次元配列
多次元配列は、複数の行と列を持つ配列のことです。サンプルコードの多次元配列は3 x 4の構造を持った二次元配列です。コードでは定義された二次元配列に対し、左上から順にアクセスして要素を取得しています。
サンプルコード:
class Sample
{
public static void Main()
{
int[,] num = new int[,]
{
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
};
foreach (var elem in num)
{
Console.Write("{0}, ", elem);
}
Console.WriteLine();
}
}
このコードを実行すると以下の画面のように、二次元配列の要素をすべて列挙します。
List
こちらはList型の変数list_strを作成し、全件をループするパターンです。
サンプルコード:
class Sample
{
public static void Main()
{
List<string> list_str = new List<string>();
list_str.Add("123");
list_str.Add("456");
list_str.Add("789");
foreach (string str in list_str)
{
Console.WriteLine(str);
}
}
}
このコードを実行すると以下の画面のように、二次元配列の要素をすべて列挙します。
Dictionary
Dictionaryでforeach文を使う場合、valueとkeyをそれぞれ取得できます。以下のサンプルコードでは、3パターンのforeach文を実行しています。
サンプルコード:
class Sample
{
public static void Main()
{
// 初期化
var sampledic = new Dictionary<string, string>(){
{"keyA", "value01"},
{"keyB", "value02"},
{"keyC", "value03"},
{"keyD", "value04"},
{"keyE", "value05"},
};
// keyとvalueを取得するforeach文
foreach (KeyValuePair<string, string> item in sampledic)
{
System.Console.WriteLine("keyは{0} valueは{1}でした", item.Key, item.Value);
}
// keyだけを取得するforeach文
foreach (var a in sampledic.Keys)
{
System.Console.WriteLine("keyは{0}でした", a);
}
// valueだけを取得するforeach文
foreach (var a in sampledic.Values)
{
System.Console.WriteLine("valueは{0}でした", a);
}
}
}
このコードを実行すると以下の画面のように、Dictionaryの要素を3つのパターンで取得します。
Indexを取得
foreach文を使って、Dictionaryのindexを取得する方法です。前項で解説した通り、foreach文はfor文と異なり、index番号を使用せずに簡潔なコードの記述が可能です。しかし、実務の中ではindex番号を使いたいケースもあります。
その場合は、LINQ(Language-Integrated Query)のSelectメソッドを使用します。LINQはさまざまなデータへのアクセスを簡潔に記述できるようにするものです。foreach文と組み合わせるのに便利な、強力な機能を多数備えています。
サンプルコードでは、foreachの条件文でSelectによってindexを取得しています。
サンプルコード:
class Sample
{
public static void Main()
{
var sampledic = new Dictionary<string, string>(){
{"リンゴ", "140円"},
{"ミカン", "60円"},
{"パイナップル", "400円"},
{"バナナ", "100円"},
{"イチゴ", "600円"},
};
// index,key,valueを取得するforeach文
foreach (var item in sampledic.Select((Entry, Index) => new { Entry, Index }))
{
System.Console.WriteLine("番号: {0}, 商品:{1}, 価格:{2}", item.Index, item.Entry.Key, item.Entry.Value);
}
}
}
このコードを実行すると以下の画面のように、Dictionaryの要素とindexを整理し、表示します。
foreach文の文中で処理する方法
foreachの繰り返し処理の中で、一定の条件に達したら処理をスキップしたり、中断したりするには、continueやbreakを使用します。
continueでスキップ
特定の要素では処理をスキップしたい場合、continueを使用します。continueを使用すると、その時点で処理がスキップされ、次のループ処理が始まります。continueより上に書かれている処理は実行されてしまうので注意しましょう。
サンプルコードは、1〜6の番号が格納された配列に対し、foreach文で1文字ずつ要素を取り出して表示する処理に、4の場合だけ処理を分岐させcontinueを組み込みました。
サンプルコード:
class Sample
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5, 6 };
foreach (int num in numbers)
{
if (num == 4)
{
// numが4の場合は処理をスキップする
Console.WriteLine("4はスキップされました", num);
continue;
}
// 画面に出力
Console.WriteLine("{0}", num);
}
}
}
このサンプルコードを実行すると、以下のようになります。continueより上に記述された「4はスキップされました」という文字列の出力が確認できました。また、continueにより次にループ処理にうつるため、Console.WriteLine の行で出力されるはずの4が出力されないこともわかります。
breakで抜ける
特定の要素では処理を終了し、ループから抜けたい場合は、breakを使用します。breakを使うと、その時点ですべての処理が停止し、foreachのループ処理自体から抜けるため、continueとは異なり、それ以後のループ処理は行われなくなります。breakより上に記述されたコードは処理されるので注意しましょう。
サンプルコードでは、1〜6の番号が格納された配列に対し、foreach文で1文字ずつ要素を取り出して表示する処理に、4の場合だけ処理を分岐させてbreakを組み込みました。
サンプルコード:
class Sample
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5, 6 };
foreach (int num in numbers)
{
if (num == 4)
{
// numが4の場合は処理を中断する
Console.WriteLine("4で処理が中断しました", num);
break;
}
Console.WriteLine("{0}", num);
}
}
}
このサンプルコードを実行すると、以下のようになります。4の場合、ifで条件を分岐し、文字列を出力してループ処理を抜けています。
foreach文はループ処理が簡潔に書ける
foreach文は、配列やList、Dictionaryなどのオブジェクト要素にアクセスして、ループ処理を書くのに便利です。for文よりも簡潔に記述できることから、ループ処理を行う際には実務上も頻繁に使用します。
foreach文とfor文のどちらが処理が速いかは状況によって変わるため、for文についても理解を深めて、使い分けを身につけておくと良いでしょう。