1. はじめに
配列でよくやりたいことって何?
基本的な操作をリストアップしよう:
- インデックスで配列の要素を読み書きする。
- 値で要素を検索する。
- 配列のコピーや「スライス」(配列の一部)を作る。
- 配列をソートする。
- 配列をリバース(逆順)する。
- 配列を特定の値で埋める。
- 要素が存在するかチェックする(配列が指定した値を含むか)。
- 長さを変更する(resize)。
実際の課題でもこういう操作はよく出てくるよ ― 例えば「4000より大きい合計ある?」とか「1000未満の最初の価格を探せ」とか「価格を昇順でソートして」みたいな感じ。
これ全部、関数でサクッとできる
| 操作 | メソッド / シンタックス | 特徴 |
|---|---|---|
| インデックスで変更 | |
範囲外だとエラー |
| 値の検索 | |
見つからなければ-1 |
| 存在チェック | |
ラムダか関数を渡す |
| ソート | |
配列自体が変わる |
| リバース | |
要素の順番が逆になる |
| コピー | |
シャローコピー |
| 埋める | |
全部同じ値で埋める |
| サイズ変更 | |
新しい要素はdefault |
| 最大/最小の検索 | |
Linqが必要 |
2. インデックスで要素を読み書きする
これはもう知ってると思うけど、簡単な例でおさらいしよう(例えば成績の配列があるとする):
// 学生の成績配列
int[] grades = { 4, 3, 5, 2, 5 };
// 最初の成績を読む
int firstGrade = grades[0];
Console.WriteLine($"最初の成績: {firstGrade}");
// 最後の成績を「優秀」(5)に変更
grades[^1] = 5;
Console.WriteLine("変更後の最後の成績: " + grades[^1]);
ここで大事なのは:インデックスは0から始まる、存在しないインデックスにアクセスしようとするとIndexOutOfRangeExceptionエラーになる ― 面接でもよく出るし、実務でもよくやるやつ。
3. 配列内で要素を検索する
配列内で要素を探して、見つかったらそのインデックスを返す関数が2つあるよ。
Array.IndexOf(value [, from])関数
Array.IndexOfは配列の先頭から指定した要素を探す。見つかったらそのインデックスを返し、なければ-1を返す。
でも、もし次の出現も探したい場合は?そのときはArray.IndexOfの第2引数に「どこから探し始めるか」のインデックスを渡す。これは前回見つかったインデックス+1にするのがコツ。
配列内の2の全ての出現箇所を探してみよう:
int[] grades = { 4, 3, 5, 2, 5, 2 };
int x = 2; // 探したい要素
int index = Array.IndexOf(grades, x);
while (index != -1)
{
Console.WriteLine($"要素 {x} は位置: {index} に見つかった");
// 次は index + 1 から探す
index = Array.IndexOf(grades, x, index + 1);
}
Array.LastIndexOf(value [, from])関数
Array.LastIndexOfは配列の末尾から指定した要素を探す。見つかったらそのインデックスを返し、なければ-1を返す。それ以外はArray.IndexOfと同じだよ。
今度は2の全ての出現箇所を末尾から探してみよう:
int[] grades = { 4, 3, 5, 2, 5, 2 };
int x = 2; // 探したい要素
int index = Array.LastIndexOf(grades, x);
while (index != -1)
{
Console.WriteLine($"要素 {x} は位置: {index} に見つかった");
// 次は index - 1 から探す
index = Array.LastIndexOf(grades, x, index - 1);
}
4. 配列に要素が存在するかチェック
要素が存在するか調べるにはContains関数がある。このメソッドは配列に指定した要素があればtrueを返す。使うにはSystem.Linqモジュールをusingで追加する必要がある。例:
using System.Linq; // もしなければ using System.Linq; を追加
bool hasExcellent = grades.Contains(5);
Console.WriteLine($"5はある? {hasExcellent}");
めっちゃシンプルでキレイだよね。
5. 配列をリバースする:Array.Reverse
配列を「逆順」にしたいときはこれを使おう:
int[] grades = { 2, 3, 4, 5 };
// 配列を逆順にする
Array.Reverse(grades);
Console.WriteLine("リバース後の成績: " + string.Join(", ", grades));
「最新データ」を探したいときや、単に逆さまの世界が好きな人にも便利。
6. 配列をソートする:Array.Sort
そのうち配列をソートしたくなるはず。最短で安全なのは標準のソート関数を使うこと:
int[] grades = { 4, 3, 5, 2, 5 };
// 昇順でソート
Array.Sort(grades);
Console.WriteLine("ソート後の成績: " + string.Join(", ", grades));
この関数は文字列もソートできるけど、アルファベット順になるよ。
降順ソート
標準のArray.Sortは昇順のみ。降順にしたいときはソート+リバースを組み合わせよう:
Array.Sort(grades); // まず昇順
Array.Reverse(grades); // それから逆順
Console.WriteLine("降順: " + string.Join(", ", grades));
注意:よく忘れがちだけど、ソートは「その場で」行われる。配列自体が変わるので、新しい配列は返されない。元の順番を残したいなら、先にコピーしておこう。
7. 配列のクローン:CloneとArray.Copy
コピーを作って元の配列を壊したくないときは、Clone()やArray.Copy()を使おう。
Clone()は配列のメソッドで、完全なコピーを返す。
Array.Copy()は、
- コピー元の配列
- コピー先の配列
- コピーする要素数
を渡す必要がある。
int[] original = { 1, 2, 3, 4, 5 };
// 方法1: Clone()
// 一次元・多次元配列どちらもOK。ただしobject型で返るのでキャストが必要:
int[] copy1 = (int[]) original.Clone();
// 方法2: Array.Copy
int[] copy2 = new int[original.Length];
Array.Copy(original, copy2, original.Length);
大事なポイント:配列がプリミティブ型(intやdouble)なら値ごとコピーされるけど、オブジェクト配列だと参照だけコピーされる!(いわゆる「シャローコピー」)
8. 配列を値で埋める:Array.Fill
配列を「全部0にしたい」とか「全部5にしたい」ってときは、便利なArray.Fillメソッドがあるよ:
int[] grades = new int[5];
Array.Fill(grades, 5); // これで全要素が5になる
Console.WriteLine("理想的な学生: " + string.Join(", ", grades));
特定の値で配列を一気に初期化したいときに便利。
9. 最大値・最小値の検索
System.Linqモジュールを使うと、配列に便利なメソッドが増える。その中に最大値・最小値を返すMax()とMin()がある。
配列の中で最大・最小の成績を探してみよう:
int maxGrade = grades.Max();
int minGrade = grades.Min();
Console.WriteLine($"最大の成績: {maxGrade}, 最小: {minGrade}");
これらのメソッドを使うにはusing System.Linq;を忘れずに追加しよう。
GO TO FULL VERSION