こんにちは!FlutterやDartの世界へようこそ。フルスタックエンジニアの先輩として、今日から君の背中をしっかりと支えていきますね。
さて、他の言語(例えばJavaScriptやJavaなど)からDartの世界に飛び込んできた開発者が、最初に「おっ、これスマートだな!」と感動しつつも、少し戸惑うポイントがあります。それが「コレクションリテラル内での `if` と `for` の活用」です。
命令的に「まず空のリストを作って、条件分岐で `add` して……」なんてコードを書く時代は、もう終わりです。Dartのコレクションリテラルを使いこなせば、驚くほど宣言的で美しいコードが書けるようになりますよ。
ここをしっかりとクリアすれば、Dartのデータ構築の基本はバッチリマスターできます!さあ、一緒にその極意を紐解いていきましょう。
—
1. 命令型から宣言型へ:何がどう違うのか?
まずは、これまでの「古い書き方」と、Dartが提案する「新しい書き方」を比較してみましょう。
例えば、「ユーザーの権限に応じて、メニューのリストを動的に組み立てたい」というよくあるシチュエーションを想像してください。
従来の「命令的」なアプローチ
// 命令的な書き方:手続きの指示に終始している
List
List
if (isAdmin) {
menu.add(‘管理者ダッシュボード’);
}
menu.add(‘設定’);
return menu;
}
この書き方でも動きますが、変数がミュータブル(変更可能)である必要があったり、手続きのステップを頭の中で追いかける必要があったりと、少しノイズが多くなりますよね。
Dartの「宣言的」なアプローチ(コレクションif)
Dartでは、リスト(やセット、マップ)の波括弧 `[…]` の中材として、直接 `if` を埋め込むことができます。
// 宣言的な書き方:データの「構造」をそのまま記述する
List
‘ホーム’,
‘プロフィール’,
if (isAdmin) ‘管理者ダッシュボード’, // 条件に一致すればここに展開される
‘設定’,
];
どうですか?まるで「こういう構成のリストです」と設計図をそのままコードにしたかのように、直感的でスッキリしていませんか?これが、Dartが愛される理由の一つです。
—
2. コレクション `if` の基本と応用
コレクション `if` は、条件に応じて要素を「含めるか、含めないか」を決定したいときに絶大な威力を発揮します。
基本構文
[
固定の要素,
if (条件式) ‘条件がtrueのときに追加される要素’,
]
さらに、もし「条件がtrueならA、falseならB」を追加したい場合は、三項演算子と組み合わせることもできますが、単に片方だけを抜き差ししたいときは `if` 単体が最もスマートです。
実践的なコード例:UIの構築データ
Flutterの現場でも、Widgetのリスト(`List
void main() {
bool isLogined = true;
int unreadCount = 3;
List
‘システムメンテナンスのお知らせ’,
if (isLogined) ‘あなた宛ての新しいメッセージがあります’,
if (unreadCount > 0) ‘未読の通知が $unreadCount 件あります’,
];
print(notifications);
// 実行結果:
// [システムメンテナンスのお知らせ, あなた宛ての新しいメッセージがあります, 未読の通知が 3 件あります]
}
脳内トレースしてみましょう。`isLogined` が `true` なので2番目の要素がスポッと挟まり、`unreadCount > 0` も満たされているので3番目の要素が生成される……。コンパイル時、あるいは評価時に綺麗に1つのリストへと統合されます。
—
3. コレクション `for` でループ展開を極める
条件分岐の次は、繰り返し処理を見ていきましょう。既存の別リストや数値の範囲から、新しいリストの要素をその場で生み出したいとき、コレクション `for` が力を発揮します。
基本構文
[
固定の要素,
for (var item in existingList) ‘加工した $item’,
]
実践的なコード例:データのトランスフォーム(変換)
例えば、IDのリストから、HTMLのタグ付き文字列のリストを一撃で生成したいとします。
void main() {
List
// for文を使って、リスト内包表記のようにデータを構築する
List
‘all’, // 固定の先頭要素
for (var category in rawCategories)
‘#${category.toUpperCase()}’, // 各要素を大文字にしてハッシュを付与
];
print(formattedCategories);
// 実行結果:
// [all, #NEWS, #SPORTS, #TECH]
}
わざわざ `.map((e) => …).toList()` とメソッドチェーンをつなぐ必要すらありません。Dartの言語仕様レベルで、この構文がエレガントに解決してくれます。
—
4. 応用編:Spread(スプレッド)演算子 `…` との組み合わせ
ここからが少しステップアップした内容ですが、Dartを深く知るあなたなら一瞬で理解できます。
もし「別のリストの要素をごっそり展開しつつ、その中でさらに条件分岐やループを回したい」場合はどうすればよいでしょうか?
ここで、スプレッド演算子(`…`)や、null許容スプレッド演算子(`…?`)の出番です。
void main() {
List
bool includeSpecial = true;
List
‘programming’,
// リストの中身をバラして展開しつつ、さらに条件をかけられる
…?optionalTags,
if (includeSpecial) …[‘expert’, ‘master’],
];
print(tags);
// 実行結果:
// [programming, dart, flutter, expert, master]
}
`…?optionalTags` は、「もし `optionalTags` が `null` でなければ中身を展開し、`null` なら何もしない(エラーにしない)」という、Null安全なDartならではの強力な構文です。これらがコレクションリテラル内でシームレスに同居できるのが、Dartの美しさです。
—
5. 陥りやすい文法エラーと注意点
最後に、初心者の開発者がやりがちな「うっかりミス」をいくつか紹介しておきます。ここで先回りして知っておけば、無駄なエラーに悩まされずに済みますよ!
注意点1:セミコロン(`;`)を入れない
通常のDartのコードブロックの中では文の終わりに `;` を書きますが、コレクションリテラル内の `if` や `for` の条件部・式の中にはセミコロンを書きません。
// ❌ 誤った書き方(コンパイルエラーになります)
List
1,
2,
if (true) {
3; // ← ここにセミコロンを入れるとエラー!
}
];
// ⭕ 正しい書き方
List
1,
2,
if (true) 3, // カンマ `,` で区切るのがルール
];
注意点2:波括弧 `{}` との勘違い
`if` の後ろに条件を書くとき、通常の `if (condition) { … }` のように波括弧をつけてしまいがちです。しかし、コレクションリテラル内では、直後に続く「1つの式(または値)」がそのまま要素になります。
複数の要素を追加したい場合は、先ほど紹介したスプレッド演算子 `…[…]` を活用しましょう。
—
まとめ
いかがでしたでしょうか?
- コレクション `if` を使えば、条件に応じた要素の有無を宣言的に記述できる。
- コレクション `for` を使えば、ループ処理による要素の展開がスマートに行える。
- スプレッド演算子と組み合わせることで、複雑なコレクションの組み立てすらも一目で分かる設計図になる。
命令的な手続き思考から脱却し、この宣言的なデータ構築手法をマスターすれば、あなたの書くDart/Flutterコードの洗練度は一段と跳ね上がります。
ここをクリアした君なら、もうDartのコレクション操作で迷うことはありません。自信を持って、次の実装へ進んでくださいね!それではまた次回の記事でお会いしましょう。