1. タプルとは?
タプルは、複数のデータをひとまとめにして管理できるものです。たとえば、名前と年齢、座標のXとYといった、関連する2つ以上の値をまとめて扱いたいときに使います。
通常、変数は一つのデータしか保存できませんが、タプルを使うと複数の異なる型のデータを1つにまとめて扱えるのが特徴です。
タプルの具体例
例えば、名前と年齢を一緒に保存する場合、以下のようにタプルを使ってまとめることができます。
(string Name, int Age) person = ("Alice", 25);
この例では、「Alice」という名前と「25」という年齢を一緒に保存しており、それぞれにアクセスすることもできます。
Console.WriteLine(person.Name); // "Alice" と表示
Console.WriteLine(person.Age); // 25 と表示
2. 配列とタプルの関係
タプルを配列で使うと、複数のタプルを一気にまとめて管理することができます。たとえば、社員のリストを名前と年齢のタプルで扱う場合は、次のようにタプルの配列を作成します。
タプルを使った配列の例
// タプルを使った配列
(string Name, int Age)[] employees = new (string, int)[2];
employees[0] = ("John", 30);
employees[1] = ("Alice", 25);
// 配列内のタプル要素にアクセス
Console.WriteLine(employees[0].Name); // "John"
Console.WriteLine(employees[1].Age); // 25
この例では、2つのタプルが配列に格納されています。それぞれの要素に、名前や年齢を一つずつ持たせています。
3. リストとタプルの関係
配列とは違い、リストはデータの数を柔軟に変更できるという特徴があります。タプルをリストで使うと、社員が増えたり減ったりする場合に便利です。
タプルを使ったリストの例
// タプルを使ったリスト
var employees = new List<(string Name, int Age)>();
employees.Add(("John", 30));
employees.Add(("Alice", 25));
// リスト内のタプル要素にアクセス
foreach (var employee in employees)
{
Console.WriteLine($"{employee.Name}, 年齢: {employee.Age}");
}
この例では、リストに社員を追加したり、繰り返し処理で全員の名前と年齢を一度に表示したりできます。リストなら要素数が自由に増減できるため、動的なデータ管理に向いています。
まとめ
タプル: 関連する複数の値をまとめる。例:(string Name, int Age)。
配列とタプル: タプルの配列で複数のデータをまとめて扱える。例:(string, int)[]。
リストとタプル: タプルのリストを使うと、データを追加・削除しやすい。例:List<(string Name, int Age)>。
これらを使い分けることで、データの管理が効率的に行えるようになります。最初はタプルに慣れるのがポイントです。
参考問題
毎年 5 月 1 日に、自分が運営している会社の社員一覧表を作成しています。表は年度ごとに更新され、社員の名前と年齢が載っています。
ところで、会社のメンバーは昨年度から全く変わらず、社員の誕生日は全員 7 月 7 日だったので、前年度の一覧表の年齢欄をそれぞれ +1 するだけで今年度の表が作れることにパイザ君は気づきました。
昨年度の一覧表が与えられるので、今年度の一覧表を出力してください。
入力例2
3
Tanaka 18
Sato 50
Suzuki 120
出力例2
Tanaka 19
Sato 51
Suzuki 121
参考解答例
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
int N = int.Parse(Console.ReadLine());
var employees = new List<(string Name, int Age)>();
for(int i = 0; i < N; i++)
{
var input = Console.ReadLine().Split(' ');
string name = input[0];
int age = int.Parse(input[1]);
employees.Add((name, age));
}
foreach(var employee in employees)
{
// 文字列補間
Console.WriteLine($"{employee.Name} {employee.Age + 1}");
}
}
}
参考解答例補足(自分向け)
1. ループ内での変数宣言の基本
ループの中で string name や int age のように変数を宣言していますが、これは各ループが回るたびに新しい変数を作っているわけではありません。
実際には、ループのたびに 同じ変数に新しい値を入れている だけです。例えば、name という変数はループのたびに新しい社員の名前を受け取りますが、ループが終わるたびにその中身が変わっているだけで、メモリに無駄にたくさんの name 変数が作られるわけではありません。
2. メモリの使い方
コンピュータがメモリを使う際、スコープという概念があります。スコープとは、「この変数がどこで使われるか」の範囲のことです。for ループの中で宣言された変数は、ループの内部だけで使われるので、ループが1回まわるごとにその変数の中身が新しい値に置き換えられます。
したがって、ループが回るたびに同じメモリの場所を再利用しているので、メモリを無駄に消費する心配はありません。
3. パフォーマンスに影響はあるか?
ループ内で変数を再利用しているので、余計なメモリが使われるわけではありません。ループの回数が非常に多い(何万回、何百万回)ときでも、メモリの効率に関して特に問題はありません。
4. 書き方の選択肢
ループの外で変数を宣言することもできますが、特別な理由がない限り、ループ内で宣言するほうがコードの見やすさや意図の明確さに貢献します。
例:
string name;
int age;
for (int i = 0; i < N; i++)
{
var input = Console.ReadLine().Split(' ');
name = input[0];
age = int.Parse(input[1]);
employees.Add((name, age));
}
これでも動作は同じですが、実際にはあまり違いはなく、むしろループ内で必要なものだけを宣言したほうが整理されていてわかりやすいです。
まとめ
- ループ内で変数を宣言しても、同じメモリを使い回しているので、余計なメモリは消費しません。
- ループ内で変数を宣言することは、パフォーマンスにも大きな影響を与えません。
- コードの可読性を保つために、ループ内で必要な変数はそこで宣言するのが一般的です。