例えばですが、以下の宣言では、各々右辺に、 {} と []の様に初期化しています。
これは、どういうルールになっているのでしょうか?
Map<int, String> cateDescription = {}; //cates-descritionインスタンス変数
List<Map<String, dynamic>> cates = []; //catesテーブルインスタンス変数
この宣言で使用されている {}
と []
は、それぞれ Dart 言語におけるマップとリストのリテラル初期化子です。
これにより、データ構造の初期化と初期値の設定が行われます。
1.初期化
(1)マップの初期化 ( {}
):
Map<int, String> cateDescription = {};
- この宣言は、
cateDescription
という名前のMap
を作成します。このマップは整数型のキー (int
) と文字列型の値 (String
) を持ちます。 {}
は空のマップを意味し、初期状態ではcateDescription
マップにはキーと値のペアが存在しません。
(2)リストの初期化 ( []
):
List<Map<String, dynamic>> cates = [];
- この宣言は、
cates
という名前のList
を作成します。このリストはMap<String, dynamic>
型の要素を持ちます。 []
は空のリストを意味し、初期状態ではcates
リストは何も要素を含んでいません。
これらの初期化は、それぞれのデータ構造が後で値を追加する準備ができている状態を作り出すために使用されます。
マップやリストは可変的なデータ構造であるため、初期化後に新たな要素やキーと値のペアを追加することができます。
以下、実際のデータを使った(上記で初期化した マップ 、 リスト への)追加例です。
2.上記の使用例
(1)マップの使用例
マップはキーと値のペアを格納するデータ構造で、キーによって直接値を参照できます。
以下の例では、整数型のキーと文字列型の値を持つマップ cateDescription
を初期化しています。
// 空のマップを初期化する
Map<int, String> cateDescription = {};
// マップにキーと値のペアを追加する例
cateDescription[1] = '仕事';
cateDescription[2] = 'プライベート';
// マップとその要素を出力する
print(cateDescription);
上記のコードでは、最初に空のマップを作成し、その後でマップにキーと値のペアを追加しています。キーには整数を使用し、値にはそれに対応する説明(カテゴリの名前など)を格納しています。
(2)リストの使用例
リストは、順序付けられた要素の集合を管理するのに使います。
以下の例では、Map<String, dynamic>
型の要素を持つリスト cates
を初期化しています。
このリストは、複数のキーと値を持つマップ(辞書型データ)の集合を格納できます。
// 空のリストを初期化する
List<Map<String, dynamic>> cates = [];
// リストにマップを追加する例
cates.add({
'cateId': 1,
'description': '仕事'
});
cates.add({
'cateId': 2,
'description': 'プライベート'
});
// リストとその要素を出力する
print(cates);
上記のコードでは、最初に空のリストを作成し、その後でリストに2つのマップを追加しています。
それぞれのマップはカテゴリのIDと説明を表しています。
3.その他のよくある事例
上記の様な(意味的に似ているのに)異なる型(形式)の情報間の変換(や抽出等のやりとり)は頻繁に必要になります。
以降、上記やその他の、よくある事例を挙げてあります。
事例1: 異なる型の間の抽出
次の⓶(テーブルデータ)から、⓵(フィールド情報)だけを抽出して下さい。
⓵ List<String> _Description = []; ※メンバとしては文字列を想定
↑抽出する
⓶ List<Map<String, dynamic>> _cates = [];
(catesテーブル情報)
"CREATE TABLE cates ("
"cateId INTEGER PRIMARY KEY AUTOINCREMENT,"
"description TEXT UNIQUE,"
…(その他省略)…
")"
↓ 抽出例:
感覚としては、冒頭例では、<int>を主キーの様にして<String>型の文字列をまとめたMapと、
そのMapをまとめたList、という前提だったのに対して、
当事例では、その<int>(いわゆる主キー的な感じ)を省略したList<String>として、
それらの(異なるフィールドを保有している)Mapから、抽出する、的な感覚、だと思います。
List<String> _Description =
_cates.map(
(c) => c['description'] as String
).toList();
上記抽出例では、(Listではありますが、そのうちの)各Mapから、某フィールド(description)について限定して(つまり、このフィールド(キー)に対応する値を抽出しています。このような、各Mapから、データを抽出する場合には、map()関数を使用します。
また(上記抽出例では)それらのListが欲しいわけですから、最後に、toList()メソッドを使用して新しいListを生成しています。
あと、(上記抽出例では)対象としているフィールド(description)は文字列を想定していますので、途中、as String でキャストしています。(もし、null の可能性がある場合は、null チェックも追加する必要があります。)
ちなみに、c の部分は、統一していれば任意の文字列で構いません。