Tips

2018.06.12

C# 基礎 第12回 データがいっぱいどうしよう(コンテナ)

データがいっぱいどうしよう(コンテナ)

皆さんお疲れ様です。
前回条件分岐文を学んでいただきました。
皆さんが着々とプログラミングを学ばれ、
コンピューターさんとのコミュニケーションを
進められていることを、とてもうれしく思います。

今回は、『コンテナ』という仕組みを学んでいただきます。
第10回で変数定義を学んでいただきました。
1つ1つのデータに名前をつけることで、データを管理しやすくなりましたね。
この応用で、いくつものデータを1つのグループとしてまとめて、名前をつける仕組みが『コンテナ』。
最初は難しいかもしれませんが、順番にご説明するのでご安心ください。

今日のラインアップ
  1. ちょっと寄り道: 変数埋め込み文字列
  2. コンテナ概要
  3. 配列
  4. リスト
  5. 連想配列
  6. 順序つき連想配列
  7. 応用編: コンテナと条件分岐の組み合わせ
  8. 実習
  9. まとめ

1. ちょっと寄り道: 変数埋め込み文字列

本題に入る前に、ひとつ、こちらの伝えこぼしを補足させていただきます。
変数定義の際、データに名前をつけることで管理しやすくなるとご説明しましたね。
でも、変数の利点はさらにあるのです!
それが、文字列と連携した、『変数埋め込み文字列』です。

$”{変数名}”とすると、
あら不思議!
変数名のところが、変数があらわすデータに置き換わります。
これから先の連載でも登場するので、
この機会に理解してしまいましょう。

変数埋め込み文字列の実例
// 変数を二つ定義します。
var firstCustomer= "Hanako";
var secondCustomer = "Taro";

// 変数埋め込み文字列を使います
// {firstCustomer}の部分が、変数firstCustomerの"Hanako"
// {secondCustomer}の部分が、変数secondCustomerの"Taro"
// 実際に表示されるのは『Hanako様とTaro様のお二方がいらっしゃいました。』です。
Console.WriteLine($"{firstCustomer}様と{secondCustomer}様のお二方がいらっしゃいました。");

寄り道失礼しました。
皆様を、本日の本題、コンテナの世界へお連れします。
章リストに戻る方はこちら

2. コンテナ概要

『コンテナ』なんていわれても、頭に?マークが出てくるだけですよね。
ちょっと、日常生活の例から話してみましょう。

私たちは日常、一つ一つのものに名前をつけています。
たとえば、桃、さくらんぼ、みかん、りんご、というように。

さらに私たちは、いくつかのものをまとめたグループにも名前をつけています。
桃、さくらんぼ、みかん、りんご、であれば、まとめて『果物』と呼んでいますね。

これと同じことをやるのに、C#ではコンテナという仕組みを使います。
いくつもあるデータを、このコンテナにまとめてしまうのです。
『関連のあるデータをひとまとめにして名前をつけたい』時に最適です。

コンテナの実例(果物の名前)
// string[]というのは、"文字列(string)が入った配列(コンテナの一種)ですよという意味
// fruitsは配列の名前。中に2つ以上のデータが入ることが前提なので、複数形にします
// {}の中に、順番にデータを書いていきます
// データの中身は、"peach"(桃), "cherry"(さくらんぼ), "tangerine"(みかん), "apple"(りんご)
// 『,』(コンマ)区切りで並べていきます
string[] fruits = {"peach", "cherry", "tangerine", "apple"};

コンテナは主なものが4種類あります。概要をご覧ください。

代表的な4種のコンテナ
  1. コンテナ1. 配列
  2. 個別のデータに0番目、1番目、2番目と番号を振ります。

  3. コンテナ2. リスト
  4. 個別のデータに0番目、1番目、2番目と番号を振ります。

  5. コンテナ3. 連想配列
  6. 個別のデータに、文字列で名前をつけます。

  7. コンテナ4. 順序つき連想配列
  8. 個別のデータに、番号をつけ、文字列で名前をつけます。

コンテナを使いこなすためには、ちょっとしたおまじないが必要です。
これから、コンテナを使う際は、以下の文言をソースコードの一番上に付け加えてください。

コンテナのためのおまじない
// デフォルトだと、自動的に用意されます
using System;
// リスト、連想配列を使うために必要です
using System.Collections.Generic;
// 順序つき連想配列を使うために必要です
using System.Collections.Specialized;
// コンテナの便利機能を使うために必要です
using System.Linq;

では、順番にコンテナを見ていきましょう。
章リストに戻る方はこちら

3. 配列

個別のデータに番号を割り当てます。
注意するのは、この番号は0番始まりだということです。
プログラミング言語によって違いますが、C#では番号は0番始まりです。

基本知識集
  1. 変数定義
  2. データ数の読み取り
  3. 個々のデータの読み取り
  4. 格納したデータの変更
  5. データの新規追加

3-1. 変数定義(知識1)

配列の変数定義では、変数名に英語の複数形を使ってください。
これが個別データの変数定義と違うところです。

フォーマットを3つ紹介します。

  1. 基本的なフォーマット
  2. 型指定キーワード[] 変数名 = {要素1, 要素2, 要素3 /*以下同じ形式*/};
    
  3. データ型指定を省略したフォーマット
  4. // 『=』の右側を見て、データ型が明らかな場合、varキーワードを使ってください。
    var 変数名 = new[] {要素1, 要素2, 要素3 /*以下同じ形式*/};
    
  5. 配列の長さだけ指定したフォーマット
  6. var 変数名 = new 型指定キーワード[要素数];
    
変数定義のソースコードの実例
// 配列定義 型指定
int[] severalEvens = {0, 2, 4, 6};

// 配列定義 型指定省略
var severalOdds = new[] {1, 3, 5, 7};

// 配列宣言(長さだけ指定)
// 型は文字列型
var arrayWhichHasThreeElements = new string[3];

3-2. データ数の読み取り(知識2)

配列の中にいくつ個別データがあるかも大事な情報です。
注意としては、データの数は1つから始まるということです。
番号は0番始まり、個数は1個から始まる。
ややこしいですね。

配列の中のデータ数を調べるには、『Length』というものを使います。
『Length』は英語で長さという意味です。
配列の長さは、配列の中のデータ数です。

データ数の取得のフォーマット
// 変数名(配列の名前)の長さという意味です。
変数名.Length
データ数の取得のソースコード実例
// いくつかの偶数を配列にする
int[] severalEvens = { 0, 2, 4, 6 };

// データの数の取得
// {}にはいった、severalEvens.Lengthが、severalEvensのデータ数を表している。
// 4つデータがあるので、『severalEvensのデータ数 : 4』が表示される。
Console.WriteLine($"severalEvensのデータ数 : {severalEvens.Length}");

3-3. 個々のデータの読み取り(知識3)

個々のデータは、番号指定で読み取ります。
何度もいいますが、0番始まりです。

データの読み取りのフォーマット
変数名[番号] /*該当する番号のデータが手に入ります*/
データの読み取りのソースコード実例
int[] severalEvens = { 0, 2, 4, 6 };

// 『severalEvensの0番目の値 : 0』と画面に表示される。
Console.WriteLine($"severalEvensの0番目の値 : {severalEvens[0]}");

3-4. 格納したデータの変更(知識4)

配列の中の個別のデータを変更する場合は、
変更したいデータの番号を使います。

データの変更のフォーマット
変数名[番号] = 変更後のデータ;
データの変更のソースコードの実例
// 変数定義
int[] severalEvens = {0, 2, 4, 6};

// 変更前の値を取得して表示
Console.WriteLine($"severalEvensの3番目の値 変更前 : {severalEvens[3]}");

// 値を変更
severalEvens[3] = 8;

// 変更後の値を取得して表示
Console.WriteLine($"severalEvensの3番目の値 変更後 : {severalEvens[3]}");

3-5. データの新規追加(知識5)

配列にデータを追加するのは大変です。
次のリストを使うのが一番です。
一応、やり方をご紹介しますが、使わないほうが無難です。

データの新規追加のフォーマット
var 新しい配列の変数名 = new 型指定キーワード[元の配列の変数名.Length + 1];
新しい配列の変数名[新しい配列の変数名.Length - 1] = 新しいデータ;
元の配列の変数名 = 新しい配列の変数名;
ソースコードの実例
// 変数定義
int[] severalEvens = { 0, 2, 4, 6 };
Console.WriteLine($"severalEvensのデータ数 変更前 : {severalEvens.Length}");

// 新しい配列severalEvensSecond(長さが元の配列severalEvensより1つ長い)を変数定義
int[] severalEvensSecond = new int[severalEvens.Length + 1];
//severalEvensSecondの最後の番号に、10を代入。
severalEvensSecond[severalEvensSecond.Length - 1] = 10;
// severalEvensの中身すべてを、severalEvensSecondで置き換え
severalEvens = severalEvensSecond;

// データ数は5
Console.WriteLine($"severalEvensのデータ数 変更後 : {severalEvens.Length}");
// 0番から数えて最後の4番目の値は10
Console.WriteLine($"severalEvensの4番目の値 : {severalEvens[4]}");

章リストに戻る方はこちら

4. リスト

配列と基本的な考え方は同じです。
データを番号で管理します。
番号は0番始まりです。

配列との違いを3つご紹介します。

配列との違い
  1. 途中で値を追加することが前提
  2. 値の読み取り処理が遅い
  3. 反面、値の変更や追加が早い

基本事項は5つ。配列と同じですね。

基本知識集
  1. 変数定義
  2. データ数の読み取り
  3. 個々のデータの読み取り
  4. 格納したデータの変更
  5. データの新規追加

4-1. 変数定義(知識1)

リストの変数定義をご説明します。
変数名は、配列同様、英語の複数形を使いましょう。
変数定義のフォーマットは以下の通りです。

変数定義のフォーマット
// {}の中に、データを『,』区切りで書いていきます。
var 変数名 = new List{要素1, 要素2, 要素3 /*以下同じ形式*/};
ソースコードの実例
var tutorialList = new List<Int32>{1, 2, 3};

4-2. データ数の読み取り(知識2)

配列のデータ数は『Length』でした。
しかし、リストのデータ数の読み取りは『Count』を使います。

データ数読み取りのフォーマット
// Countは、個別データの数という意味です。
変数名.Count
データ数読み取りのソースコード実例
var tutorialList = new List<Int32>{1, 2, 3};
// データ数取得
Console.WriteLine($"tutorialListのデータ数 : {tutorialList.Count}");

4-3. 個々のデータの読み取り(知識3)

値の読み取りは、配列と同じ形式で行います。

個々のデータの読み取りのフォーマット
// 該当する番号のデータが読み取れます
変数名[番号]
個々のデータの読み取りのソースコード実例
var tutorialList = new List<Int32>{1, 2, 3};
// データ数取得
Console.WriteLine($"tutorialListの0番目のデータ : {tutorialList[0]}");

4-4. 格納したデータの変更(知識4)

格納したデータの変更も、配列と同じやり方です。

格納したデータの変更フォーマット
変数名[番号] = データ;
格納したデータの変更をするソースコードの実例
// リストを定義
var tutorialList = new List<Int32>{1, 2, 3};

Console.WriteLine($"tutorialListの1番目の値 変更前 : {tutorialList[1]}");
tutorialList[1] = 5;
Console.WriteLine($"tutorialListの1番目の値 変更後 : {tutorialList[1]}");

4-5. データの新規追加(知識5)

やり方が2つあります。
1つが、末尾に追加するやり方。
もうひとつが、指定した番号のところに割り込ませるやり方です。

データの新規追加フォーマット
// 末尾に追加
変数名.Add(新しいデータ)

// 指定した番号(0番始まり)にデータを割り込ませる
// 最後+1の番号のときは、新しく末尾にデータが追加
// すでにある番号に割り込ませた場合、それ以降のデータと番号の対応が1つ後ろにずれる
変数名.Insert(番号, 新しいデータ);
データの新規追加のソースコード実例
// リストを定義
var tutorialList = new List<Int32>{1, 2, 3};

// 値を末尾に追加
Console.WriteLine($"tutorialListのデータ数 値追加前 : {tutorialList.Count}");
tutorialList.Add(4);
Console.WriteLine($"tutorialListのデータ数 値追加後 : {tutorialList.Count}");
Console.WriteLine($"tutorialListの3番目の値 : {tutorialList[3]}");

// 値の割り込ませ
Console.WriteLine($"tutorialListのデータ数 値追加前 : {tutorialList.Count}");
tutorialList.Insert(4, 5);
Console.WriteLine($"tutorialListのデータ数 値追加後 : {tutorialList.Count}");
Console.WriteLine($"tutorialListの4番目の値 : {tutorialList[4]}");

ちなみに、配列に新しくデータを追加するのは難しいといいました。
でも、リストを作って、新しくデータを追加し、最後にそのリストを配列に変えるのは簡単です。

リストにデータを新しく追加し、配列に変えるソースコード実例
// リストを変数定義
var fewIntegersAsList = {0, 1, 2};

// 最後に新しいデータを追加
fewIntegersAsList.Add(3);

// 配列に変換
var fewIntegersAsArray = fewIntegersAsList.ToArray();

章リストに戻る方はこちら

5. 連想配列

配列やリストでは、個別のデータに番号を割り振りました。
連想配列では、個別のデータに、一つ一つ名前を割り振ります。
基本的には、名前は文字列です。
この、個別データの名前を『キー』と呼びます。

基本知識集
  1. 変数定義
  2. データ数の読み取り
  3. 個々のデータの読み取り
  4. 格納したデータの変更
  5. データの新規追加

5-1. 変数定義(知識1)

変数定義のフォーマットは、配列やリストより少し手間がかかります。
番号が自動的に割り振られるのではなく、皆さんが個別のデータのためのキーを決めなければいけないからです。
もっとも大事なことは、同じキーを2回以上使わないことです。
理由は後述します。

また、変数名は、配列やリストと違い、はっきりとした習慣が固定化されていません。
ただし、キーとデータの両方についての情報が、変数名に含まれていることが必要です。

変数定義のフォーマット
var 変数名 = new Dictionary{
    {キー, データ}
    , {キー, データ}
    , {キー, データ}
    /* 以下同じ形式*/
};
変数定義のソースコード実例
// 変数定義
var fewPairsOfPrefectureAndCapital = new Dictionary<string, string> {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

5-2. データ数の読み取り(知識2)

連想配列の中にいくつデータが入っているか調べるには、
リストと同じように、『Count』を使います。

データ数の取得フォーマット
変数名.Count
データ数の取得のソースコード実例
 // 変数定義
var fewPairsOfPrefectureAndCapital = new Dictionary<string, string> {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

// データ数取得
// ここでは『fewPairsOfPrefectureAndCapitalのデータ数 : 3』と表示されます。
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 : {fewPairsOfPrefectureAndCapital.Count}");

5-3. 個々のデータの読み取り(知識3)

個々のデータを読み取るには、キーを使います。
変数定義の時、同じキーは2つ以上使わないようお願いしました。
理由は、キーを使ってデータを読み取るとき、コンピューターさんが『同じキーで2つ以上データがあるよ、どっちだ?』と迷子になってしまうのを防ぐためです。

データ読み取りのフォーマット
変数名[対応するキー]
データ読み取りのソースコードの実例
// 変数定義
var fewPairsOfPrefectureAndCapital = new Dictionary<string, string> {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

// 値参照
// 『Okinawaのキーに対応する値 : Naha}』と表示されます。
Console.WriteLine($"Okinawaのキーに対応する値 : {fewPairsOfPrefectureAndCapital["Okinawa"]}");

5-4. 格納したデータの変更(知識4)

格納したデータを変更するためには、対応するキーと、変更後のデータを『=』で結び付けてあげます。

格納された個別データ変更のフォーマット
変数名[対応するキー] = 変更後のデータ;
格納された個別データ変更のソースコード実例
// 変数定義
var fewPairsOfPrefectureAndCapital = new Dictionary<string, string> {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

// 値変更
// 『"Kagoshimaのキーに対応する値 変更前 : Unknown』と表示されます
Console.WriteLine($"Kagoshimaのキーに対応する値 変更前 : {fewPairsOfPrefectureAndCapital["Kagoshima"]}");

// Kagoshimaのキーに結び付けられたデータを、UnknownからKagoshimaに変更します。
fewPairsOfPrefectureAndCapital["Kagoshima"] = "Kagoshima";

// 『Kagoshimaのキーに対応する値 変更後 : Kagoshima』と表示されます。
Console.WriteLine($"Kagoshimaのキーに対応する値 変更後 : {fewPairsOfPrefectureAndCapital["Kagoshima"]}");

5-5. データの新規追加(知識5)

連想配列にデータを追加するときは、キーとデータのセットを追加することになります。
二つやり方があります。

データの新規追加のフォーマット
やり方1. 
変数名[新しいデータのための新しいキー] = 新しいデータ;

やり方2.
変数名.Add(新しいデータのための新しいキー, 新しいデータ);
データの新規追加のソースコード実例
// 都道府県をキー、県庁所在地をデータとした連想配列
var fewPairsOfPrefectureAndCapital = new Dictionary<string, string> {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

// やり方1.
// 『fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : 3』
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : {fewPairsOfPrefectureAndCapital.Count}");
// 新しいキーのChibaと、新しいデータのChibaを追加
fewPairsOfPrefectureAndCapital["Chiba"] = "Chiba";
//『fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : 4』
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : {fewPairsOfPrefectureAndCapital.Count}");
// 『Chibaのキーに対応する値 : Chiba』と表示される
Console.WriteLine($"Chibaのキーに対応する値 : {fewPairsOfPrefectureAndCapital["Chiba"]}");

// やり方2.
// 『fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : 4』と表示される
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : {fewPairsOfPrefectureAndCapital.Count}");
// 新しいキーのOsakaと、新しいデータのOsakaを追加
fewPairsOfPrefectureAndCapital.Add("Osaka", "Osaka");
// 『fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : 5』と表示される
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : {fewPairsOfPrefectureAndCapital.Count}");
// 『Osakaのキーに対応する値 : Osaka』と表示される。
Console.WriteLine($"Osakaのキーに対応する値 : {fewPairsOfPrefectureAndCapital["Osaka"]}");

ちなみに、やり方2で、すでにあるキーを間違って付け加えようとすると、エラーになります。

エラーソースコード実例
// これはエラーになります。
// すでに"Kagoshima"というキーが登録されているからです。
fewPairsOfPrefectureAndCapital.Add(key:"Kagoshima", value:"Kagoshima");

章リストに戻る方はこちら

6. 順序つき連想配列

データをキーでも、番号でも管理したいという意欲溢れる皆さん。
朗報です!
順序つき連想配列は、連想配列と配列・リストの性質を併せ持っています。
個別のデータを、キーと番号の両方で管理できます。

おなじみの基本知識5種類です。

基本知識集
  1. 変数定義
  2. データ数の読み取り
  3. 個々のデータの読み取り
  4. 格納したデータの変更
  5. データの新規追加

6-1. 変数定義(知識1)

変数定義の方法は、連想配列とおおむね一緒です。

変数定義フォーマット
var 変数名 = new OrderedDictionary{
    {キー, データ}
    , {キー, データ}
    , {キー, データ}
    /* 以下同じ形式*/
};
変数定義ソースコード実例
// 変数定義
var fewPairsOfPrefectureAndCapital = new OrderedDictionary {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

6-2. データ数の読み取り(知識2)

データ数の読み取りは、リスト連想配列と同じく、『Count』を使います。

データ数取得のフォーマット
変数名.Count
データ数取得のソースコードの実例
// 変数定義
var fewPairsOfPrefectureAndCapital = new OrderedDictionary {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

// データ数取得
// ここでは『fewPairsOfPrefectureAndCapitalのデータ数 : 3』が表示されます。
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 : {fewPairsOfPrefectureAndCapital.Count}");

6-3. 個々のデータの読み取り(知識3)

個々のデータを読み取るやり方は2つあります。
1つが、連想配列式に、キーで読み取るやり方
もう1つが、配列リスト同様に、番号で読み取るやり方。

データの読み取りのフォーマット
// やり方1
変数名[対応するデータの番号]

// やり方2
変数名[対応するデータのキー]
データの読み取りのソースコード実例
// 変数定義
var fewPairsOfPrefectureAndCapital = new OrderedDictionary {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

// やり方1. キーでデータを読み取ります
// ここでは、『Okinawaのキーに対応する値 : Naha』が表示されます。
Console.WriteLine($"Okinawaのキーに対応する値 : {fewPairsOfPrefectureAndCapital["Okinawa"]}");

// やり方2. 番号でデータを読み取ります。
// ここでは、『0番目の値 : Naha』が表示されます。
Console.WriteLine($"0番目の値 : {fewPairsOfPrefectureAndCapital[0]}");

6-4. 格納したデータの変更(知識4)

格納したデータを変更するやり方も、2つあります。
1つが、連想配列と同じやり方。キーを指定して、そのキーのデータを変更します。
もう1つが、配列リストと同じやり方。番号を指定して、その番号のデータを変更します。

データの変更のフォーマット
やり方1.
変数名[対応するキー] = 変更後のデータ;
やり方2. 
変数名[対応する番号] = 変更後のデータ;
ソースコードの実例
// 変数定義
var fewPairsOfPrefectureAndCapital = new OrderedDictionary {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};


//やり方1. 特定のキーに対応するデータを変更します

// 『Kagoshimaのキーに対応する値 変更前 : Unknown』
Console.WriteLine($"Kagoshimaのキーに対応する値 変更前 : {fewPairsOfPrefectureAndCapital["Kagoshima"]}");

// Kagoshimaのキーに対応するデータがUnknownからKagoshimaに変更される。
fewPairsOfPrefectureAndCapital["Kagoshima"] = "Kagoshima";

//『Kagoshimaのキーに対応する値 変更前 : Kagoshima』とコンソール画面に表示される。
Console.WriteLine($"Kagoshimaのキーに対応する値 変更後 : {fewPairsOfPrefectureAndCapital["Kagoshima"]}");


// やり方2. 特定の番号に対応するデータを変更します

//『2番目の値 変更前 : Unknown』と表示される
Console.WriteLine($"2番目の値 変更前 : {fewPairsOfPrefectureAndCapital[2]}");

// 2番目の値が	UnknownからHiroshimaに変更される
fewPairsOfPrefectureAndCapital[2] = "Hiroshima";

//『2番目の値 変更前 : Hiroshima』と表示される
Console.WriteLine($"2番目の値 変更後 : {fewPairsOfPrefectureAndCapital[2]}");

6-5. データの新規追加(知識5)

データを新規追加するやり方は、なんと3つあります。
連想配列と同じやり方が2つ。
そして、リストと似たやり方が1つです。

データの新規追加のフォーマット
やり方1. 末尾に新しいキーとデータを追加する。連想配列と同じ。
変数名[新しいデータのための新しいキー] = 新しいデータ;

やり方2. 末尾に新しいキーとデータを追加する。連想配列と同じ。
変数名.Add(新しいデータのための新しいキー, 新しいデータ);

やり方3. 指定した番号に、新しいキーとデータを割り込ませる。リストと似ている。
変数名.Insert(番号, 新しいデータのための新しいキー, 新しいデータ);
ソースコードの実例
// 都道府県をキー、県庁所在地をデータとした順序付き連想配列
var fewPairsOfPrefectureAndCapital = new OrderedDictionary {
    { "Okinawa", "Naha"}
    , { "Kagoshima", "Unknown"}
    , { "Hiroshima", "Unknown"}
};

// やり方1.
// 『fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : 3』
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : {fewPairsOfPrefectureAndCapital.Count}");
// 新しいキーのChibaと、新しいデータのChibaを追加
fewPairsOfPrefectureAndCapital["Chiba"] = "Chiba";
//『fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : 4』
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : {fewPairsOfPrefectureAndCapital.Count}");
// 『Chibaのキーに対応する値 : Chiba』と表示される
Console.WriteLine($"Chibaのキーに対応する値 : {fewPairsOfPrefectureAndCapital["Chiba"]}");

// やり方2.
// 『fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : 4』と表示される
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : {fewPairsOfPrefectureAndCapital.Count}");
// 新しいキーのOsakaと、新しいデータのOsakaを追加
fewPairsOfPrefectureAndCapital.Add("Osaka", "Osaka");
// 『fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : 5』と表示される
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : {fewPairsOfPrefectureAndCapital.Count}");
// 『Osakaのキーに対応する値 : Osaka』と表示される。
Console.WriteLine($"Osakaのキーに対応する値 : {fewPairsOfPrefectureAndCapital["Osaka"]}");

// やり方3. 指定した番号に、新しいキーとデータを割り込ませる
// fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : 5
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加前 : {fewPairsOfPrefectureAndCapital.Count}");
// fewPairsOfPrefectureAndCapitalの5番目(0番始まり)に、Ehimeというキーと、Matsuyamaというデータを割り込ませる
fewPairsOfPrefectureAndCapital.Insert(5, "Ehime", "Matsuyama");
// fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : 6
Console.WriteLine($"fewPairsOfPrefectureAndCapitalのデータ数 値追加後 : {fewPairsOfPrefectureAndCapital.Count}");
// Ehimeのキーに対応する値 : Matsuyama
Console.WriteLine($"Ehimeのキーに対応する値 : {fewPairsOfPrefectureAndCapital["Ehime"]}");
// 5番目の値 : Matsuyama
Console.WriteLine($"5番目の値 : {fewPairsOfPrefectureAndCapital[5]}");

ちなみに、やり方2では、連想配列の時同様、すでにあるキーを指定すると、エラーになります。

章リストに戻る方はこちら

7. 応用編: コンテナと条件分岐の組み合わせ

お疲れ様です。
最後に応用編として、ちょっとだけ高度な内容をみてみましょう。
if文との組み合わせで、リストや配列の性質に応じた条件分岐を実現します。

応用編紹介
  1. 特定のデータが含まれているか
  2. すべてのデータが特定の条件を満たすか
  3. どれか1つ以上のデータが特定の条件を満たすか

7-1. 特定のデータが含まれているか(応用1)

特定のデータが配列やリストに含まれているかを調べます。

フォーマット
変数名.Contains(調査対象データ)
ソースコードの実例
// いくつかの花の名前のある配列
string[] flowers = {"rose", "tulip", "lily"};

// もし(if)、花たち(flowers)が"lily"を含んでいる(Contains)なら
if(flowers.Contains("lily")
{
    // コンソール画面に、『lilyがflowersに含まれています。』と表示する。
    Console.WriteLine("lilyがflowersに含まれています。");
}

7-2. すべてのデータが特定の条件を満たすか(応用2)

配列やリストの個別データについて、すべてのデータが特定の条件を満たすかを調べます。

フォーマット
変数名.All(個別データ名 => すべての個別データが満たすべき条件)
ソースコードの実例
// いくつかの整数のある配列
int[] someIntegers = {17, 18, 19};

// もし(if)、整数たち(someIntegers)の中で、
// すべて(All)の個別の整数(integer)について、その整数(integer)が20より小さい(<)なら
if(someIntegers.All(integer => integer < 20))
{
    // コンソール画面に、『someIntegersの中の整数はすべて20より小さいです。』と表示する。
    Console.WriteLine("someIntegersの中の整数はすべて20より小さいです。");
}

7-3. どれか1つ以上のデータが特定の条件を満たすか(応用3)

配列やリストの個別データについて、どれか1つ以上のデータが特定の条件を満たすかを調べます。

フォーマット
変数名.Any(個別データ名 => どれか1つ以上の個別データが満たすべき条件)
ソースコードの実例
// 果物たちの配列(fruits)を変数定義
string[] fruits = {"peach", "grape", "apple"};
// もし(if)、果物たち(fruits)の中で、
// どれか1つ以上(Any)の個別の果物(fruit)について、その果物(fruit)が"apple"と同じ(==)なら
if(fruits.Any(fruit => fruit == "apple"))
{
    // コンソール画面に、『fruitsの中にはappleがあります。』と表示する。
    Console.WriteLine("fruitsの中にはappleがあります。");
}

章リストに戻る方はこちら

8. 実習

問題1. 次の問題文にしたがって、データをコンテナにまとめてください。

野菜(vegetables)が5種類あります。
にんじん(carrot)、たまねぎ(onion)、じゃがいも(potato)、キャベツ(cabbage)、セロリ(celery)です。
英語名をキー、日本語名(漢字かな混じり)をデータとして、
連想配列にまとめてください。
順序はつけないでください。
名前は、englishJapaneseMapOfVegerableNamesとしてください。
解答例
[csharp] var englishJapaneseMapOfVegetableNames = new Dictionary<string, string>{
{"carrot", "にんじん"}
, {"onion", "たまねぎ"}
, {"potato", "じゃがいも"}
, {"cabbage", "キャベツ"}
, {"celery", "セロリ"}
};
[/csharp]

問題2. 以下のコンテナは不適切です。改善理由も添えて、ソースコードを書き換えてください。

改善対象

var birds = new List<String>{"owl", "hawk", "pigeon"};
Console.WriteLine($"{birds[0]}はbirdsの0番目のデータです。");
解答例
[csharp] // 改善した:
// 最初に定義されたデータを読むだけなのに、リストは必要ない
// 配列を使うべき。
string[] birds = {"owl", "hawk", "pigeon"};
Console.WriteLine($"{birds[0]}はbirdsの0番目のデータです。");
[/csharp]

問題3. 以下の日本語の内容を、C#で表現してください。

データ数が4つ、データの型が文字列型の配列を変数定義してください。
データは、日本の都市のローマ字表記としてください。
変数名は、severalJapaneseCitiesとしてください。

次に、severalJapaneseCitiesのランダムな番号を得るために、乱数を使います。
0から3までのどれかの整数になる乱数を作り、
randomIndexという名前を付けてください。

最後に、『ランダムに選ばれた日本の都市 : (severalJapaneseCitiesの中の、ランダムな番号に対応するデータ)』と、
コンソール画面に表示してください。
解答例
[csharp] string[] severalJapaneseCities = {"Kyoto", "Osaka", "Tokyo", "Hakodate"};
int randomIndex= (new Random()).Next(0, 4);
Console.WriteLine($"ランダムに選ばれた日本の都市 : {severalJapaneseCities[randomIndex]}");
[/csharp]
章リストに戻る方はこちら

9. まとめ

皆さんお疲れ様です。
データをグループ化できれば、
数が多くても、簡単に管理できますね。
次は、繰り返し文です。
コンテナと相性がいいものもありますから、
楽しみにしてくださいね。
章リストに戻る方はこちら
最初から読み直したい方はこちら

ゲーム制作関連のオススメ連載リンク

とっても手軽なゲーム制作体験!
Unityゲーム開発基礎

実際のリリースゲームを題材にしたハンズオンゲーム制作連載
実践unityゲーム開発

Recent News

Recent Tips

Tag Search