# 配列

## 練習課題

[記入できるファイルをダウンロード](https://class.illogic.games/attachments/11)

### C#を読みましょう

以下の表は、C#で書いた命令とその日本語の意味が書いてある。空枠を完成してください。

<table border="1" id="bkmrk-c%23-%E6%97%A5%E6%9C%AC%E8%AA%9E-int-%5B%5D-number" style="border-collapse: collapse; width: 100%; height: 429.7px;"><colgroup><col style="width: 43.1477%;"></col><col style="width: 56.8523%;"></col></colgroup><thead><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**C#**

</td><td class="align-center" style="height: 29.8px;">**日本語**</td></tr></thead><tbody><tr style="height: 66.2px;"><td style="height: 66.2px;">```c#
int [] numbers = new int[10]
```

</td><td style="height: 66.2px;">10個の整数が入る「numbers」という配列を作成</td></tr><tr style="height: 66.2px;"><td style="height: 66.2px;">```c#
int [] numbers;
```

</td><td style="height: 66.2px;"><details><summary>答え</summary>

整数型の配列を宣言のみ（初期化なし）

</details></td></tr><tr style="height: 66.2px;"><td style="height: 66.2px;">```c#
string [] names = new string[5];
```

</td><td style="height: 66.2px;"><details><summary>答え</summary>

5個の文字列が入る「names」という配列を作成

</details></td></tr><tr style="height: 59.3px;"><td style="height: 59.3px;"><details><summary>答え</summary>

```c#
names[0] = "たろう";
```

</details></td><td style="height: 59.3px;">「names」配列の一番最初（先頭）は「たろう」にする</td></tr><tr style="height: 16.5px;"><td style="height: 16.5px;"><details><summary>答え</summary>

```c#
names[4] = "おおはら";
```

</details></td><td style="height: 16.5px;">「names」配列の一番最後（後尾）は「おおはら」にする</td></tr><tr style="height: 66.2px;"><td style="height: 66.2px;">```c#
int a = numbers[3];
```

</td><td style="height: 66.2px;"><details><summary>答え</summary>

配列「numbers」の先頭から４つ目の要素を変数「a」の中に代入

</details></td></tr><tr style="height: 59.3px;"><td style="height: 59.3px;"><details><summary>答え</summary>

```c#
float [] distances = new float[3];
distances[0] = 1.3f;
distances[1] = 4.5f;
distances[2] = 7.9f;

// または
float [] distances = 
   new float[3] { 1.3f, 4.5f, 7.9f };
```

</details></td><td style="height: 59.3px;">少数型の配列「distances」を宣言し、1.3f, 4.5f, 7.9f の３つの数値で初期化する</td></tr></tbody></table>

### C#の処理を完成してみましょう

１．配列とfor文を使い、以下のスクリプトを完成してください（UnityでもOK）  
 ※：文字列の長さは「変数名.Length」で求めることができる  
 例：

```c#
string s = "Hello!";
int size = s.Length; // 文字列「s」の長さを求める
Debug.Log(size); // 6 を表示する
```

 ※：期待の結果は「最も長いフルーツ名は: grapefruit」

```c#
// フルーツの名前の配列
string [] fruits = {"lemon", "mikan", "orange", "grapefruit", "kiwi"};

// 最も長い文字列（結果）
string maxFruit = "";

// フルーツ1個ずつ確認
for (________; _________; ________)
{
    // i番目のフルーツを求める
    string f = _______________;

    // もし、今回のフルーツ名の方が長ければ
    if (f.Length > maxFruit.Length)
    {
        // 最も長いフルーツを更新
        ___________________;
    }
}

// 最大の長さのフルーツ名を表示
Debug.Log($"最も長いフルーツ名は: {______________}");
```

<details id="bkmrk-%E7%AD%94%E3%81%88-%2F%2F-%E3%83%95%E3%83%AB%E3%83%BC%E3%83%84%E3%81%AE%E5%90%8D%E5%89%8D%E3%81%AE%E9%85%8D%E5%88%97-str"><summary>答え</summary>

```c#
// フルーツの名前の配列
string [] fruits = {"lemon", "mikan", "orange", "grapefruit", "kiwi"};

// 最も長い文字列（結果）
string maxFruit = "";

// フルーツ1個ずつ確認
for (int i = 0; i < 5; i++)
{
    // i番目のフルーツを求める
    string f = fruits[i];

    // もし、今回のフルーツ名の方が長ければ
    if (f.Length > maxFruit.Length)
    {
        // 最も長いフルーツを更新
        maxFruit = f;
    }
}

// 最大の長さのフルーツ名を表示
Debug.Log($"最も長いフルーツ名は: {maxFruit}");
```

</details>２．配列とfor文を使い、以下のスクリプトを完成してください（UnityでもOK）

```c#
// 4人分のスコア（整数型）の配列を準備してください
_____ scores = ___________;

//１人目のスコアは100点
__________= 100;

//２人目のスコアは80点
__________= 80;

//３人目のスコアは180点
__________= 180;

//４人目のスコアは20点
__________= 20;

// 同様に、4人分の名前（文字列型）の配列を準備してください
// それぞれの名前は「太郎」「さくら」「オオハラ」「Unity」

______ names = __________;
_______________;
_______________;
_______________;
_______________;

// for文を使って一人ずつのプレーヤーとスコアを表示する
for (________; _________; ________)
{
    Debug.Log($"名前：{________} → {_________}");
}
```

<details id="bkmrk-%E7%AD%94%E3%81%88-%2F%2F-4%E4%BA%BA%E5%88%86%E3%81%AE%E3%82%B9%E3%82%B3%E3%82%A2%EF%BC%88%E6%95%B4%E6%95%B0%E5%9E%8B%EF%BC%89%E3%81%AE%E9%85%8D"><summary>答え</summary>

```c#
// 4人分のスコア（整数型）の配列を準備してください
int[] scores = int[4];

//１人目のスコアは100点
scores[0] = 100;

//２人目のスコアは80点
scores[1] = 80;

//３人目のスコアは180点
scores[2] = 180;

//４人目のスコアは20点
scores[3] = 20;

// 同様に、4人分の名前（文字列型）の配列を準備してください
// それぞれの名前は「太郎」「さくら」「オオハラ」「Unity」

string[] names = string[4];
names[0] = "太郎";
names[1] = "さくら";
names[2] = "オオハラ";
names[3] = "Unity";

// for文を使って一人ずつのプレーヤーとスコアを表示する
for (int i = 0; i < 4; i++)
{
    Debug.Log($"名前：{names[i]} → {score[i]}");
}
```

</details>## 自由に伸びる配列 : List

 配列を作るときに、事前にサイズを決めないといけないが、場合により、サイズが分からない可能性がある。例えば、同じゲームでも、プレーヤーによって拾うアイテムの数が変わるので、事前にアイテムの配列のサイズが分からない。

 その場合は、サイズが自動的に変わる「リスト」を使うと便利。「List」は、要素を増やすほど、段々サイズが伸びる"配列"（正しい名称は「コレクション」）である。

 便利であるが、弱点もある：リストは配列と比べて処理が遅い。数十～数百の要素以内だったら、あまり違いがないが、要素を増やすほど（数万程度）、Listの方が明らかに遅い。

### Listの宣言、使い方

<table border="1" id="bkmrk-%E5%AE%A3%E8%A8%80-list%3C%E5%9E%8B%3E-%E5%A4%89%E6%95%B0%E5%90%8D%3B-%E4%BB%A3%E5%85%A5%EF%BC%88%E4%BD%9C" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 16.012%;"></col><col style="width: 84.1072%;"></col></colgroup><tbody><tr><td>宣言</td><td>```c#
List<型> 変数名;
```

</td></tr><tr><td>代入（作成）</td><td>```c#
変数名 = new List<型>();
```

</td></tr></tbody></table>

例：

```c#
// 名前のリストを作成
List<string> names = new List<string>();

// リストに名前を追加する
names.Add("たろう");
names.Add("さくら");
names.Add("おおはら");

// 0番目の名前を表示（配列と同じ）
Debug.Log(names[0]); // 「たろう」を表示

// 要らなくなった場合、リストから削除できる
names.Remove("たろう");

// 0番目の名前を表示（配列と同じ）
Debug.Log(names[0]); // 「さくら」を表示
```

### 練習

プレーヤーのスコアを表示するスクリプトを配列からリストに書き換える

<details id="bkmrk-%E7%AD%94%E3%81%88-%2F%2F-%E3%82%B9%E3%82%B3%E3%82%A2%EF%BC%88%E6%95%B4%E6%95%B0%E5%9E%8B%EF%BC%89%E3%81%AE%E3%83%AA%E3%82%B9%E3%83%88%E3%82%92%E6%BA%96"><summary>答え</summary>

```c#
// スコア（整数型）のリストを準備してください
List<int> scores = new List<int>();

//１人目のスコアは100点
scores.Add(100);

//２人目のスコアは80点
scores.Add(80);

//３人目のスコアは180点
scores.Add(180);

//４人目のスコアは20点
scores.Add(20);

// 同様に、4人分の名前（文字列型）の配列を準備してください
// それぞれの名前は「太郎」「さくら」「オオハラ」「Unity」
List<string> names = new List<string>();
names.Add("太郎");
names.Add("さくら");
names.Add("オオハラ");
names.Add("Unity");

// for文を使って一人ずつのプレーヤーとスコアを表示する
for (int i = 0; i < 4; i++)
{
    Debug.Log($"名前：{names[i]} → {score[i]}");
}
```

</details>## 配列・リスト専用の繰り返し命令 : foreach

「for」を使って配列をループする方法を見てきた。変数を使って、インデックスを0から配列の最後まで一つずつ繰り返す。例えば：

```c#
string [] names = string[4] { "アリス", "ボブ", "チャーリー", "ジョン" };
for (int i= 0; i < 4; i++)
{
  string n = names[i]
  Debug.Log(n);
}
```

C#では、配列やリストをもっと簡単にループする方法がある。「`foreach`」（フォー・イーチ）を使うと、インデックス用の変数を用意しなくても、リストの各要素を順番に取り出すことができる。先ほどの例はこうなる：

```c#
string [] names = string[4] { "アリス", "ボブ", "チャーリー", "ジョン" };
foreach(string n in names)
{
  Debug.Log(n);
}
```

ただし、注意点が二つある。

1. `foreach`は常に要素を一つずつ順番に処理する。一部の要素をスキップしたい場合は、通常の`for`ループを使う必要がある。
2. `foreach`は読み取り専用である。リストや配列の要素を変更したい場合も、通常の`for`ループを使う必要がある。

### 練習

最も長いフルーツの名前を求めるスクリプトを更新し、`for`から`foreach`に書き換える

<details id="bkmrk-%E7%AD%94%E3%81%88-%2F%2F-%E3%83%95%E3%83%AB%E3%83%BC%E3%83%84%E3%81%AE%E5%90%8D%E5%89%8D%E3%81%AE%E9%85%8D%E5%88%97-str-1"><summary>答え</summary>

```c#
// フルーツの名前の配列
string [] fruits = ["lemon", "mikan", "orange", "grapefruit", "kiwi"];

// 最も長い文字列（結果）
string maxFruit = "";

// フルーツ1個ずつ確認
foreach(string f in fruits)
{
    // もし、今回のフルーツ名の方が長ければ
    if (f.Length > maxFruit.Length)
    {
        // 最も長いフルーツを更新
        maxFruit = f;
    }
}

// 最大の長さのフルーツ名を表示
Debug.Log($"最も長いフルーツ名は: {maxFruit}");
```

</details>