【入門編】Dartのコレクションリテラルにおける「if」と「for」の活用:宣言的なデータ構築の極意 – Dart コア文法・オブジェクト指向・Null安全解析バイブル

こんにちは!FlutterやDartの世界へようこそ。フルスタックエンジニアの先輩として、今日から君の背中をしっかりと支えていきますね。

さて、他の言語(例えばJavaScriptやJavaなど)からDartの世界に飛び込んできた開発者が、最初に「おっ、これスマートだな!」と感動しつつも、少し戸惑うポイントがあります。それが「コレクションリテラル内での `if` と `for` の活用」です。

命令的に「まず空のリストを作って、条件分岐で `add` して……」なんてコードを書く時代は、もう終わりです。Dartのコレクションリテラルを使いこなせば、驚くほど宣言的で美しいコードが書けるようになりますよ。

ここをしっかりとクリアすれば、Dartのデータ構築の基本はバッチリマスターできます!さあ、一緒にその極意を紐解いていきましょう。

—

1. 命令型から宣言型へ:何がどう違うのか?

まずは、これまでの「古い書き方」と、Dartが提案する「新しい書き方」を比較してみましょう。

例えば、「ユーザーの権限に応じて、メニューのリストを動的に組み立てたい」というよくあるシチュエーションを想像してください。

従来の「命令的」なアプローチ

// 命令的な書き方:手続きの指示に終始している
List getMenu(bool isAdmin) {
List menu = [‘ホーム’, ‘プロフィール’];

if (isAdmin) {
menu.add(‘管理者ダッシュボード’);
}

menu.add(‘設定’);
return menu;
}

この書き方でも動きますが、変数がミュータブル(変更可能)である必要があったり、手続きのステップを頭の中で追いかける必要があったりと、少しノイズが多くなりますよね。

Dartの「宣言的」なアプローチ(コレクションif)

Dartでは、リスト(やセット、マップ)の波括弧 `[…]` の中材として、直接 `if` を埋め込むことができます。

// 宣言的な書き方:データの「構造」をそのまま記述する
List getMenu(bool isAdmin) => [
‘ホーム’,
‘プロフィール’,
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 notifications = [
‘システムメンテナンスのお知らせ’,
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 rawCategories = [‘news’, ‘sports’, ‘tech’];

// for文を使って、リスト内包表記のようにデータを構築する
List formattedCategories = [
‘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? optionalTags = [‘dart’, ‘flutter’];
bool includeSpecial = true;

List tags = [
‘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 numbers = [
1,
2,
if (true) {
3; // ← ここにセミコロンを入れるとエラー!
}
];

// ⭕ 正しい書き方
List numbers = [
1,
2,
if (true) 3, // カンマ `,` で区切るのがルール
];

注意点2:波括弧 `{}` との勘違い

`if` の後ろに条件を書くとき、通常の `if (condition) { … }` のように波括弧をつけてしまいがちです。しかし、コレクションリテラル内では、直後に続く「1つの式(または値)」がそのまま要素になります。

複数の要素を追加したい場合は、先ほど紹介したスプレッド演算子 `…[…]` を活用しましょう。

—

まとめ

いかがでしたでしょうか?

  • コレクション `if` を使えば、条件に応じた要素の有無を宣言的に記述できる。
  • コレクション `for` を使えば、ループ処理による要素の展開がスマートに行える。
  • スプレッド演算子と組み合わせることで、複雑なコレクションの組み立てすらも一目で分かる設計図になる。

命令的な手続き思考から脱却し、この宣言的なデータ構築手法をマスターすれば、あなたの書くDart/Flutterコードの洗練度は一段と跳ね上がります。

ここをクリアした君なら、もうDartのコレクション操作で迷うことはありません。自信を持って、次の実装へ進んでくださいね!それではまた次回の記事でお会いしましょう。

タイトルとURLをコピーしました