Dartには標準で強力なコレクション(データ構造)が備わっています。
順序付きリスト List、重複を許さない集合 Set、キーと値のペア Map は、いずれもジェネリクスによって厳密に型安全です。
さらにDart独自の特徴として、リストやマップの定義内で直接条件分岐やループを展開できる コレクション if / for や スプレッド演算子 があり、FlutterのWidgetツリーを構築する上で不可欠なテクニックとなっています。
この章では、コレクションの基礎から高度なデータ操作・変換までを学びます。
List、Set、Map とジェネリクスDartの代表的なコレクション型には、List、Set、Map があります。
すべてジェネリクス(<T>)に対応しており、要素の型がコンパイル時に厳格にチェックされます。
List: 順序付き配列角括弧 [] を使ってリテラルを定義します。
void main() {
// 型推論により List<String> になる
var fruits = ['apple', 'banana', 'orange'];
fruits.add('grape');
print('要素数: ${fruits.length}');
print('0番目: ${fruits[0]}');
print('全要素: $fruits');
}dart run list_basics.dart要素数: 4 0番目: apple 全要素: [apple, banana, orange, grape]
Set: 重複のない集合波括弧 {} を使い、要素のみをカンマ区切りで並べます。
void main() {
// Set<int>
var numbers = {1, 2, 3, 2, 1};
numbers.add(4);
numbers.add(3); // 重複は無視される
print('Setの要素: $numbers');
print('2を含むか: ${numbers.contains(2)}');
}dart run set_basics.dartSetの要素: {1, 2, 3, 4}
2を含むか: trueMap: キーと値のペア波括弧 {} を使い、key: value 形式で記述します。
void main() {
// Map<String, int>
var scores = {
'Alice': 95,
'Bob': 80,
};
scores['Charlie'] = 88; // 要素の追加・更新
print('Aliceの点数: ${scores['Alice']}');
print('存在しないキー: ${scores['Dave']}'); // null が返る
}dart run map_basics.dartAliceの点数: 95 存在しないキー: null
if、for とスプレッド演算子Dartのコレクションリテラル内では、要素の生成ロジックとして if、for、スプレッド演算子を直接埋め込むことができます。
これにより、動的なリスト生成を非常に宣言的かつクリーンに記述できます。
if条件が true の場合のみ要素をコレクションに含めます。
void main() {
bool isAdmin = true;
bool isGuest = false;
var navItems = [
'ホーム',
'プロフィール',
if (isAdmin) '管理者パネル',
if (isGuest) 'ログイン案内',
];
print(navItems);
}dart run collection_if.dart[ホーム, プロフィール, 管理者パネル]
forループを使って複数の要素を動的に展開してコレクションを構築します。
void main() {
var numbers = [1, 2, 3];
var stringList = [
'#0',
for (var n in numbers) '#$n',
];
print(stringList);
}dart run collection_for.dart[#0, #1, #2, #3]
... / ...?)既存のコレクションの全要素を別のコレクション内に展開して埋め込みます。対象が null になり得る場合は ...?(Null認識スプレッド演算子) を使用します。
void main() {
var baseList = [1, 2];
List<int>? extraList; // null
var combined = [
0,
...baseList,
...?extraList, // null なので展開を安全にスキップ
3,
];
print(combined);
}dart run spread_operator.dart[0, 1, 2, 3]
Dartのコレクション(Iterable)には、関数型プログラミングスタイルでデータを操作・集計するための便利な高階メソッド(where, map, reduce, fold など)が用意されています。
where と map による抽出・変換where: 条件を満たす(コールバックが true を返す)要素のみを抽出します。map: 各要素を変換関数で別の値に写像します。toList(): 遅延評価される Iterable を List に確定します。void main() {
final numbers = [1, 2, 3, 4, 5, 6];
// 偶数だけを抽出し、それぞれを2乗してListに変換
final result = numbers
.where((n) => n.isEven)
.map((n) => n * n)
.toList();
print('元のリスト: $numbers');
print('変換後: $result');
}dart run map_where.dart元のリスト: [1, 2, 3, 4, 5, 6] 変換後: [4, 16, 36]
reduce と fold による集計reduce: リストの先頭要素を初期値として要素を1つの値にまとめます(空リストではエラー)。fold: 明示的な初期値を指定して集計を開始します(空リストでも安全、型変換も可能)。void main() {
final numbers = [10, 20, 30, 40];
// reduce による合計
final sum = numbers.reduce((acc, curr) => acc + curr);
print('合計 (reduce): $sum');
// fold による初期値 100 からの加算
final totalWithBase = numbers.fold<int>(100, (acc, curr) => acc + curr);
print('ベース値付き合計 (fold): $totalWithBase');
// fold で文字列結合
final joined = numbers.fold<String>('値:', (acc, curr) => '$acc $curr');
print('文字列 (fold): $joined');
}dart run reduce_fold.dart合計 (reduce): 100 ベース値付き合計 (fold): 200 文字列 (fold): 値: 10 20 30 40
この章では、Dartのコレクションと強力な制御構文について学びました。
List、一意集合の Set、キー値ペアの Map を提供。if / for: リテラル宣言の中で条件分岐やループを展開し、宣言的なリスト生成が可能。..., ...?): コレクション要素の展開や、Null安全なリスト結合を実現。where(絞り込み)、map(変換)、reduce / fold(集計・畳み込み)をチェーンして簡潔にデータ加工ができる。次の 第5章 では、Dart 3で導入された目玉機能である レコード(Records)とパターンマッチング について学びます。
ユーザー権限と追加オプションに応じたメニュー一覧のリストを生成してください。
bool isPremium = true;List<String>? betaFeatures = ['AIアシスタント', '高速検索'];if、コレクション for、スプレッド演算子を活用して、以下の要素を持つ List<String> menu を生成する。
'ホーム''設定'isPremium が true の場合のみ 'プレミアム限定動画'betaFeatures が null でなければその全要素を展開'ログアウト'menu の中身を出力する。void main() {
// ここにコードを書いてください
}dart run practice4_1.dart商品データのリストから条件に合う商品を抽出し、合計金額を算出するプログラムを作成してください。
Map<String, dynamic> のリスト)を用意する。
final items = [
{'name': 'ノートPC', 'price': 120000, 'inStock': true},
{'name': 'マウス', 'price': 3000, 'inStock': false},
{'name': 'キーボード', 'price': 15000, 'inStock': true},
{'name': 'モニター', 'price': 45000, 'inStock': true},
];
where を使って在庫がある(inStock == true)商品のみに絞り込む。map で各商品の価格(price as int)を取り出す。fold を使って価格の総額を計算し、'在庫あり商品の合計金額: xxx 円' と出力する。void main() {
// ここにコードを書いてください
}dart run practice4_2.dart