0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter入門 第5回】Dart のコレクション ― List・Map・Set と便利メソッド

0
Posted at

はじめに

Flutter入門シリーズ第5回は Dart のコレクション です。

Flutter アプリでは、API から取得したデータの一覧表示、フォームの入力値管理、状態の保持など、あらゆる場面でコレクション(List・Map・Set)を扱います。Dart のコレクションには、mapwherefold といった強力なメソッドや、スプレッド演算子・コレクション if/for など他の言語にはない独自機能があります。

この記事では、各コレクションの基本操作から実践的な活用パターンまでをコード例とともに解説します。すべてのコード例は void main() {} を含む完全な形で掲載しているので、DartPad にそのまま貼り付けて実行できます。


List

作成とアクセス

List は順序付きのコレクションです。[] リテラルで作成し、インデックス(0始まり)でアクセスします。

void main() {
  // リテラルで作成
  var fruits = ['りんご', 'バナナ', 'みかん'];

  print(fruits[0]);      // りんご
  print(fruits[1]);      // バナナ
  print(fruits.length);  // 3

  // 最初と最後の要素
  print(fruits.first);   // りんご
  print(fruits.last);    // みかん

  // 要素の変更
  fruits[1] = 'ぶどう';
  print(fruits);         // [りんご, ぶどう, みかん]
}

型付きリスト

型パラメータを指定すると、異なる型の要素を追加できなくなります。Flutter のコードでは常に型を指定するのが一般的です。

void main() {
  List<int> scores = [85, 92, 78, 95, 88];
  // scores.add('文字列'); // コンパイルエラー: String は追加できない

  List<String> names = ['田中', '佐藤', '鈴木'];

  // 空リストの作成(型推論が効かないため型指定が必要)
  List<double> prices = [];
  prices.add(1980.0);
  prices.add(2500.0);
  print(prices); // [1980.0, 2500.0]
}

追加・削除

void main() {
  var list = [1, 2, 3];

  // 末尾に追加
  list.add(4);
  print(list); // [1, 2, 3, 4]

  // 複数追加
  list.addAll([5, 6]);
  print(list); // [1, 2, 3, 4, 5, 6]

  // 指定位置に挿入
  list.insert(0, 0);
  print(list); // [0, 1, 2, 3, 4, 5, 6]

  // 値を指定して削除(最初に見つかった1つ)
  list.remove(3);
  print(list); // [0, 1, 2, 4, 5, 6]

  // インデックスを指定して削除
  list.removeAt(0);
  print(list); // [1, 2, 4, 5, 6]

  // 条件に合う要素をすべて削除
  list.removeWhere((e) => e % 2 == 0);
  print(list); // [1, 5]

  // 全削除
  list.clear();
  print(list); // []
}

List.generate()

規則的なリストを生成するときに便利です。

void main() {
  // 0〜9 のリスト
  var numbers = List.generate(10, (index) => index);
  print(numbers); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  // 2の累乗のリスト
  var powers = List.generate(5, (index) => 1 << index);
  print(powers); // [1, 2, 4, 8, 16]

  // 文字列のリスト
  var items = List.generate(3, (index) => 'アイテム${index + 1}');
  print(items); // [アイテム1, アイテム2, アイテム3]
}

計算の確認:

  • 1 << 0 = 1, 1 << 1 = 2, 1 << 2 = 4, 1 << 3 = 8, 1 << 4 = 16

List の便利メソッド

map ― 各要素を変換

map は各要素に関数を適用し、新しい Iterable を返します。toList() で List に変換できます。

void main() {
  var numbers = [1, 2, 3, 4, 5];

  // 各要素を2倍にする
  var doubled = numbers.map((n) => n * 2).toList();
  print(doubled); // [2, 4, 6, 8, 10]

  // 文字列に変換
  var labels = numbers.map((n) => '第${n}位').toList();
  print(labels); // [第1位, 第2位, 第3位, 第4位, 第5位]
}

where ― 条件でフィルタリング

void main() {
  var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

  // 偶数のみ抽出
  var evens = numbers.where((n) => n % 2 == 0).toList();
  print(evens); // [2, 4, 6, 8, 10]

  // 5より大きい値
  var large = numbers.where((n) => n > 5).toList();
  print(large); // [6, 7, 8, 9, 10]
}

any / every ― 条件判定

void main() {
  var scores = [85, 92, 78, 95, 88];

  // いずれかが90以上か?
  print(scores.any((s) => s >= 90));   // true

  // すべてが70以上か?
  print(scores.every((s) => s >= 70)); // true

  // すべてが90以上か?
  print(scores.every((s) => s >= 90)); // false
}

reduce / fold ― 畳み込み

reduce は最初の要素を初期値として、要素を順番に結合します。fold は初期値を明示的に指定できます。

void main() {
  var numbers = [1, 2, 3, 4, 5];

  // reduce: 合計を計算(初期値はリストの最初の要素)
  var sum = numbers.reduce((a, b) => a + b);
  print('合計: $sum'); // 合計: 15

  // fold: 初期値を指定して合計を計算
  var sumWithFold = numbers.fold<int>(0, (acc, n) => acc + n);
  print('合計(fold): $sumWithFold'); // 合計(fold): 15

  // fold: 初期値100から引いていく
  var result = numbers.fold<int>(100, (acc, n) => acc - n);
  print('100 - 1 - 2 - 3 - 4 - 5 = $result'); // 100 - 1 - 2 - 3 - 4 - 5 = 85

  // reduce: 最大値を求める
  var max = numbers.reduce((a, b) => a > b ? a : b);
  print('最大値: $max'); // 最大値: 5

  // fold で文字列リストを結合
  var words = ['Dart', 'は', '楽しい'];
  var sentence = words.fold<String>('', (acc, w) => acc + w);
  print(sentence); // Dartは楽しい
}

計算の確認:

  • reduce: ((((1+2)+3)+4)+5) = 15
  • fold(100, -): 100 - 1 - 2 - 3 - 4 - 5 = 85

sort / reversed

void main() {
  var numbers = [3, 1, 4, 1, 5, 9, 2, 6];

  // 昇順ソート(元のリストが変更される)
  numbers.sort();
  print(numbers); // [1, 1, 2, 3, 4, 5, 6, 9]

  // 降順ソート
  numbers.sort((a, b) => b.compareTo(a));
  print(numbers); // [9, 6, 5, 4, 3, 2, 1, 1]

  // reversed は Iterable を返す(元のリストは変更されない)
  var reversed = numbers.reversed.toList();
  print(reversed); // [1, 1, 2, 3, 4, 5, 6, 9]

  // 文字列のソート
  var names = ['鈴木', '田中', '佐藤', '高橋'];
  names.sort();
  print(names); // [佐藤, 田中, 鈴木, 高橋]
}

contains / indexOf

void main() {
  var fruits = ['りんご', 'バナナ', 'みかん', 'バナナ'];

  print(fruits.contains('バナナ'));   // true
  print(fruits.contains('いちご'));   // false

  print(fruits.indexOf('みかん'));    // 2
  print(fruits.indexOf('いちご'));    // -1(見つからない場合)
  print(fruits.lastIndexOf('バナナ')); // 3(最後に見つかった位置)
}

スプレッド演算子 ...

... を使うと、リストの中に別のリストの要素を展開できます。

void main() {
  var list1 = [1, 2, 3];
  var list2 = [4, 5, 6];

  // リストの結合
  var combined = [...list1, ...list2];
  print(combined); // [1, 2, 3, 4, 5, 6]

  // 要素の追加を伴う結合
  var withExtra = [0, ...list1, 99, ...list2];
  print(withExtra); // [0, 1, 2, 3, 99, 4, 5, 6]

  // null 安全スプレッド演算子 ...?
  List<int>? nullableList;
  var safe = [1, 2, ...?nullableList, 3];
  print(safe); // [1, 2, 3]
}

コレクション if / for

Dart 独自の機能で、リストリテラルの中に iffor を書けます。Flutter の UI 構築で非常に頻繁に使われるパターンです。

コレクション if

void main() {
  bool isAdmin = true;
  bool showDebug = false;

  var menu = [
    'ホーム',
    'プロフィール',
    if (isAdmin) '管理画面',
    if (showDebug) 'デバッグ',
    '設定',
  ];
  print(menu); // [ホーム, プロフィール, 管理画面, 設定]
}

isAdmintrue なので '管理画面' が含まれ、showDebugfalse なので 'デバッグ' は含まれません。

コレクション for

void main() {
  var baseNumbers = [1, 2, 3];

  // 各要素を2倍にしたリスト
  var doubled = [
    for (var n in baseNumbers) n * 2,
  ];
  print(doubled); // [2, 4, 6]

  // 範囲を使った生成
  var squares = [
    for (var i = 1; i <= 5; i++) i * i,
  ];
  print(squares); // [1, 4, 9, 16, 25]

  // if と for の組み合わせ
  var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  var evenSquares = [
    for (var n in numbers)
      if (n % 2 == 0) n * n,
  ];
  print(evenSquares); // [4, 16, 36, 64, 100]
}

計算の確認:

  • evenSquares: 偶数 2,4,6,8,10 の二乗 → [4, 16, 36, 64, 100]

Map

作成とアクセス

Map はキーと値のペアを保持するコレクションです。{} リテラルで作成します。

void main() {
  // リテラルで作成
  var scores = {
    '田中': 85,
    '佐藤': 92,
    '鈴木': 78,
  };

  // アクセス(戻り値は nullable)
  print(scores['田中']);  // 85
  print(scores['高橋']);  // null(存在しないキー)

  // 型指定
  Map<String, int> ages = {
    'Alice': 25,
    'Bob': 30,
  };

  print(ages.length); // 2
}

追加・更新・削除

void main() {
  var capitals = <String, String>{};

  // 追加
  capitals['日本'] = '東京';
  capitals['アメリカ'] = 'ワシントンD.C.';
  capitals['フランス'] = 'パリ';
  print(capitals);
  // {日本: 東京, アメリカ: ワシントンD.C., フランス: パリ}

  // 更新(同じキーに代入)
  capitals['日本'] = '東京都';
  print(capitals['日本']); // 東京都

  // 削除
  capitals.remove('フランス');
  print(capitals);
  // {日本: 東京都, アメリカ: ワシントンD.C.}

  // キーの存在確認
  print(capitals.containsKey('日本'));    // true
  print(capitals.containsKey('イギリス')); // false

  // 値の存在確認
  print(capitals.containsValue('東京都')); // true
}

キーと値の取得

void main() {
  var scores = {'田中': 85, '佐藤': 92, '鈴木': 78};

  print(scores.keys);    // (田中, 佐藤, 鈴木)
  print(scores.values);  // (85, 92, 78)
  print(scores.entries); // (MapEntry(田中: 85), MapEntry(佐藤: 92), MapEntry(鈴木: 78))

  // List に変換
  var keyList = scores.keys.toList();
  print(keyList); // [田中, 佐藤, 鈴木]
}

putIfAbsent

キーが存在しない場合のみ値を追加します。

void main() {
  var config = {'theme': 'dark', 'language': 'ja'};

  // 'theme' は既に存在するので変更されない
  config.putIfAbsent('theme', () => 'light');
  print(config['theme']); // dark

  // 'fontSize' は存在しないので追加される
  config.putIfAbsent('fontSize', () => '16');
  print(config['fontSize']); // 16
  print(config); // {theme: dark, language: ja, fontSize: 16}
}

forEach / entries を使った反復

void main() {
  var scores = {'田中': 85, '佐藤': 92, '鈴木': 78};

  // forEach
  scores.forEach((key, value) {
    print('$key: $value点');
  });
  // 田中: 85点
  // 佐藤: 92点
  // 鈴木: 78点

  // entries を使った for-in
  for (var entry in scores.entries) {
    print('${entry.key} の成績は ${entry.value}点です');
  }
  // 田中 の成績は 85点です
  // 佐藤 の成績は 92点です
  // 鈴木 の成績は 78点です
}

Set

作成と基本操作

Set は重複しない要素のコレクションです。要素の順序は保証されますが、インデックスによるアクセスはできません。

void main() {
  // リテラルで作成
  var fruits = {'りんご', 'バナナ', 'みかん', 'りんご'};
  print(fruits);        // {りんご, バナナ, みかん}(重複は除去される)
  print(fruits.length); // 3

  // 型指定
  Set<int> numbers = {1, 2, 3};

  // 追加
  numbers.add(4);
  numbers.add(2); // 既に存在するので追加されない
  print(numbers); // {1, 2, 3, 4}

  // 削除
  numbers.remove(3);
  print(numbers); // {1, 2, 4}

  // 存在確認
  print(numbers.contains(2)); // true
  print(numbers.contains(9)); // false
}

注意: 空の {} は Map として解釈されます。空の Set を作るには <int>{}Set<int>() と書きます。

集合演算

Set は数学の集合演算をサポートしています。

void main() {
  var a = {1, 2, 3, 4, 5};
  var b = {3, 4, 5, 6, 7};

  // 和集合(union)
  print(a.union(b));        // {1, 2, 3, 4, 5, 6, 7}

  // 積集合(intersection)
  print(a.intersection(b)); // {3, 4, 5}

  // 差集合(difference): a にあって b にないもの
  print(a.difference(b));   // {1, 2}

  // b にあって a にないもの
  print(b.difference(a));   // {6, 7}
}

Set の活用: ユニーク値の抽出

void main() {
  var responses = ['賛成', '反対', '賛成', '中立', '賛成', '反対', '中立'];

  // ユニークな回答を抽出
  var unique = responses.toSet();
  print(unique); // {賛成, 反対, 中立}

  // 各回答の数をカウント
  for (var answer in unique) {
    var count = responses.where((r) => r == answer).length;
    print('$answer: $count票');
  }
  // 賛成: 3票
  // 反対: 2票
  // 中立: 2票
}

Iterable の概念

ListSetMap.keysMap.values はすべて Iterable を実装しています。Iterable は「順番に要素を取り出せる」という共通のインターフェースです。

mapwhere などのメソッドは Iterable を返します。これらは 遅延評価(lazy evaluation) で動作し、実際に値が必要になるまで計算を行いません。

void main() {
  var numbers = [1, 2, 3, 4, 5];

  // map と where は Iterable を返す(この時点では計算されない)
  var result = numbers
      .where((n) => n % 2 == 0)
      .map((n) => n * 10);

  print(result.runtimeType); // MappedIterable<int, int>

  // toList() や for-in で値を取り出すと計算が実行される
  print(result.toList()); // [20, 40]

  // Iterable を直接 for-in で使う
  for (var value in result) {
    print(value);
  }
  // 20
  // 40
}

計算の確認: 偶数 [2, 4] を10倍 → [20, 40]


実践的な例: 成績管理

void main() {
  var students = [
    {'name': '田中', 'math': 85, 'english': 72, 'science': 90},
    {'name': '佐藤', 'math': 92, 'english': 88, 'science': 84},
    {'name': '鈴木', 'math': 78, 'english': 95, 'science': 82},
    {'name': '高橋', 'math': 65, 'english': 70, 'science': 88},
  ];

  // 各生徒の平均点を計算
  print('=== 個人成績 ===');
  for (var student in students) {
    var math = student['math'] as int;
    var english = student['english'] as int;
    var science = student['science'] as int;
    var avg = (math + english + science) / 3;
    print('${student["name"]}: 平均 ${avg.toStringAsFixed(1)}点');
  }
  // === 個人成績 ===
  // 田中: 平均 82.3点
  // 佐藤: 平均 88.0点
  // 鈴木: 平均 85.0点
  // 高橋: 平均 74.3点

  // 数学の最高点を取った生徒
  students.sort((a, b) => (b['math'] as int).compareTo(a['math'] as int));
  print('\n数学トップ: ${students.first["name"]}${students.first["math"]}点)');
  // 数学トップ: 佐藤(92点)

  // 全科目80点以上の生徒
  var honor = students.where((s) {
    return (s['math'] as int) >= 80 &&
        (s['english'] as int) >= 80 &&
        (s['science'] as int) >= 80;
  }).toList();
  var honorNames = honor.map((s) => s['name']).join(', ');
  print('\n全科目80点以上: $honorNames');
  // 全科目80点以上: 佐藤
}

計算の確認:

  • 田中: (85 + 72 + 90) / 3 = 247 / 3 = 82.333...82.3
  • 佐藤: (92 + 88 + 84) / 3 = 264 / 3 = 88.0
  • 鈴木: (78 + 95 + 82) / 3 = 255 / 3 = 85.0
  • 高橋: (65 + 70 + 88) / 3 = 223 / 3 = 74.333...74.3
  • 全科目80点以上: 佐藤(数学92, 英語88, 理科84)

実践的な例: 単語カウント

void main() {
  var text = 'dart is great and dart is fun and dart is easy';
  var words = text.split(' ');

  // 単語の出現回数をカウント
  Map<String, int> wordCount = {};
  for (var word in words) {
    wordCount[word] = (wordCount[word] ?? 0) + 1;
  }

  print('単語数: ${words.length}');     // 単語数: 12
  print('ユニーク単語数: ${wordCount.length}'); // ユニーク単語数: 6

  // 出現回数が多い順にソート
  var sorted = wordCount.entries.toList()
    ..sort((a, b) => b.value.compareTo(a.value));

  print('\n--- 単語出現回数 ---');
  for (var entry in sorted) {
    var bar = '█' * entry.value;
    print('${entry.key.padRight(6)} $bar (${entry.value}回)');
  }
  // --- 単語出現回数 ---
  // dart   ███ (3回)
  // is     ███ (3回)
  // and    ██ (2回)
  // great  █ (1回)
  // fun    █ (1回)
  // easy   █ (1回)
}

計算の確認: "dart is great and dart is fun and dart is easy" を分割 → 12単語。dart: 3回、is: 3回、and: 2回、great: 1回、fun: 1回、easy: 1回。


実践的な例: ユニーク値の抽出とデータ変換

void main() {
  // 注文データ
  var orders = [
    {'product': 'コーヒー', 'price': 350, 'quantity': 2},
    {'product': 'サンドイッチ', 'price': 500, 'quantity': 1},
    {'product': 'コーヒー', 'price': 350, 'quantity': 1},
    {'product': 'ケーキ', 'price': 450, 'quantity': 3},
    {'product': 'サンドイッチ', 'price': 500, 'quantity': 2},
  ];

  // ユニークな商品名を抽出
  var products = orders.map((o) => o['product'] as String).toSet();
  print('取り扱い商品: $products');
  // 取り扱い商品: {コーヒー, サンドイッチ, ケーキ}

  // 商品ごとの合計金額
  print('\n--- 商品別売上 ---');
  for (var product in products) {
    var total = orders
        .where((o) => o['product'] == product)
        .map((o) => (o['price'] as int) * (o['quantity'] as int))
        .fold<int>(0, (sum, amount) => sum + amount);
    print('$product: ${total}円');
  }
  // --- 商品別売上 ---
  // コーヒー: 1050円
  // サンドイッチ: 1500円
  // ケーキ: 1350円

  // 全体の合計
  var grandTotal = orders
      .map((o) => (o['price'] as int) * (o['quantity'] as int))
      .fold<int>(0, (sum, amount) => sum + amount);
  print('\n合計: ${grandTotal}円');
  // 合計: 3900円
}

計算の確認:

  • コーヒー: 350*2 + 350*1 = 700 + 350 = 1050
  • サンドイッチ: 500*1 + 500*2 = 500 + 1000 = 1500
  • ケーキ: 450*3 = 1350
  • 合計: 1050 + 1500 + 1350 = 3900

練習問題

練習問題1: List の操作

整数のリスト [12, 5, 8, 23, 17, 3, 19, 42, 7, 15] に対して、以下の処理を行うプログラムを作成してください。

  1. 10以上の要素だけを抽出する
  2. 抽出した要素をそれぞれ2倍にする
  3. 結果を昇順にソートして出力する
  4. ソートした結果の合計値を出力する

期待する出力:

10以上の要素: [12, 23, 17, 19, 42, 15]
2倍: [24, 46, 34, 38, 84, 30]
昇順ソート: [24, 30, 34, 38, 46, 84]
合計: 256
模範解答
void main() {
  var numbers = [12, 5, 8, 23, 17, 3, 19, 42, 7, 15];

  // 10以上の要素を抽出
  var filtered = numbers.where((n) => n >= 10).toList();
  print('10以上の要素: $filtered'); // [12, 23, 17, 19, 42, 15]

  // 2倍にする
  var doubled = filtered.map((n) => n * 2).toList();
  print('2倍: $doubled'); // [24, 46, 34, 38, 84, 30]

  // 昇順ソート
  doubled.sort();
  print('昇順ソート: $doubled'); // [24, 30, 34, 38, 46, 84]

  // 合計
  var sum = doubled.fold<int>(0, (acc, n) => acc + n);
  print('合計: $sum'); // 256
}

計算の確認: 24 + 30 + 34 + 38 + 46 + 84 = 256


練習問題2: Map の操作

以下の商品リストから、カテゴリ別に商品を分類して出力するプログラムを作成してください。

var items = [
  {'name': 'りんご', 'category': '果物', 'price': 150},
  {'name': 'にんじん', 'category': '野菜', 'price': 100},
  {'name': 'バナナ', 'category': '果物', 'price': 200},
  {'name': 'キャベツ', 'category': '野菜', 'price': 180},
  {'name': 'みかん', 'category': '果物', 'price': 120},
  {'name': 'トマト', 'category': '野菜', 'price': 250},
];

期待する出力:

--- 果物 ---
  りんご: 150円
  バナナ: 200円
  みかん: 120円
  平均価格: 156.7円
--- 野菜 ---
  にんじん: 100円
  キャベツ: 180円
  トマト: 250円
  平均価格: 176.7円
模範解答
void main() {
  var items = [
    {'name': 'りんご', 'category': '果物', 'price': 150},
    {'name': 'にんじん', 'category': '野菜', 'price': 100},
    {'name': 'バナナ', 'category': '果物', 'price': 200},
    {'name': 'キャベツ', 'category': '野菜', 'price': 180},
    {'name': 'みかん', 'category': '果物', 'price': 120},
    {'name': 'トマト', 'category': '野菜', 'price': 250},
  ];

  // カテゴリ別に分類
  Map<String, List<Map<String, Object>>> grouped = {};
  for (var item in items) {
    var category = item['category'] as String;
    grouped.putIfAbsent(category, () => []);
    grouped[category]!.add(item);
  }

  // カテゴリ別に出力
  for (var entry in grouped.entries) {
    print('--- ${entry.key} ---');
    for (var item in entry.value) {
      print('  ${item["name"]}: ${item["price"]}円');
    }

    // 平均価格
    var total = entry.value
        .map((item) => item['price'] as int)
        .fold<int>(0, (sum, price) => sum + price);
    var avg = total / entry.value.length;
    print('  平均価格: ${avg.toStringAsFixed(1)}円');
  }
  // --- 果物 ---
  //   りんご: 150円
  //   バナナ: 200円
  //   みかん: 120円
  //   平均価格: 156.7円
  // --- 野菜 ---
  //   にんじん: 100円
  //   キャベツ: 180円
  //   トマト: 250円
  //   平均価格: 176.7円
}

計算の確認:

  • 果物: (150 + 200 + 120) / 3 = 470 / 3 = 156.666...156.7
  • 野菜: (100 + 180 + 250) / 3 = 530 / 3 = 176.666...176.7

練習問題3: Set とコレクション操作の組み合わせ

2つのクラスの履修者リストから、以下の情報を求めるプログラムを作成してください。

var mathClass = ['田中', '佐藤', '鈴木', '高橋', '伊藤'];
var scienceClass = ['佐藤', '高橋', '渡辺', '山本', '田中'];
  1. 両方のクラスを履修している生徒
  2. 数学のみ履修している生徒
  3. 理科のみ履修している生徒
  4. いずれかのクラスを履修している全生徒(重複なし)

期待する出力:

両方履修: {佐藤, 高橋, 田中}
数学のみ: {鈴木, 伊藤}
理科のみ: {渡辺, 山本}
全生徒: {田中, 佐藤, 鈴木, 高橋, 伊藤, 渡辺, 山本}
模範解答
void main() {
  var mathClass = ['田中', '佐藤', '鈴木', '高橋', '伊藤'];
  var scienceClass = ['佐藤', '高橋', '渡辺', '山本', '田中'];

  var mathSet = mathClass.toSet();
  var scienceSet = scienceClass.toSet();

  // 両方履修(積集合)
  print('両方履修: ${mathSet.intersection(scienceSet)}');
  // 両方履修: {佐藤, 高橋, 田中}

  // 数学のみ(差集合)
  print('数学のみ: ${mathSet.difference(scienceSet)}');
  // 数学のみ: {鈴木, 伊藤}

  // 理科のみ(差集合)
  print('理科のみ: ${scienceSet.difference(mathSet)}');
  // 理科のみ: {渡辺, 山本}

  // 全生徒(和集合)
  print('全生徒: ${mathSet.union(scienceSet)}');
  // 全生徒: {田中, 佐藤, 鈴木, 高橋, 伊藤, 渡辺, 山本}
}

まとめ

コレクション リテラル 特徴
List<T> [] 順序あり、重複可、インデックスアクセス
Map<K, V> {} キーと値のペア、キーは重複不可
Set<T> <T>{} 順序あり、重複不可、集合演算が可能
機能 対応メソッド / 構文
変換 map()
フィルタリング where()
判定 any(), every(), contains()
畳み込み reduce(), fold()
ソート sort(), reversed
展開 ...(スプレッド演算子)
条件付き要素 コレクション if
ループ生成 コレクション for

次回(第6回)は Dart の Null Safety を学びます。null の安全な扱い方は Flutter 開発で必須の知識です。その後、第7回からはいよいよ Flutter のウィジェットに進んでいきます。Listmap やコレクション if/for は、Flutter の UI を宣言的に構築するときに頻繁に使うパターンです。


参考


@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?