Menu
CoddyTech

foldでリストを合計する

CoddyのFlutterジャーニー「状態管理」セクションの一部。レッスン 8/27。

支出のリストには合計が必要です。ループして足し合わせることもできますが、リストにはまさにそれを行うメソッドがあります。それが fold です。リストをたどり、項目から項目へ1つの値を引き継ぎます。

double total = expenses.fold(0.0, (sum, e) => sum + e.amount);

次のように読みます。0.0 から始めます。各支出 e について、新しい sum は古い sum に e.amount を足した値です。リストの処理が終わると、最後の sum が結果になります。3.5 と 12 の場合は、0.0、次に 3.5、そして 15.5 になります。

関数は新しい合計を返さなければなりません。e.amount だけを返すと、各ステップでそれまでの値が忘れられ、「合計」は最後の価格になってしまいます。

リスト自体は変更できます。setState 内で expenses.add(...) を呼び出すと項目が1つ追加され、次のビルドで新しいリストが合計されます。

challenge icon

チャレンジ

簡単

合計の行は常に $0.00 と表示されます。代わりに、計算してみましょう。

  • 各支出の amount を加算して、expenses.fold を使って total を設定します。

この行はすでに小数点以下2桁で表示するため、Total: $15.50 と表示され、おやつを追加すると増えていきます。

自分で試してみよう

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class Expense {
  Expense({required this.name, required this.amount});

  final String name;
  final double amount;
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final List<Expense> expenses = [
    Expense(name: 'Coffee', amount: 3.5),
    Expense(name: 'Lunch', amount: 12),
  ];

  @override
  Widget build(BuildContext context) {
    double total = 0;
    return Scaffold(
      appBar: AppBar(title: const Text('Expenses')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            for (final e in expenses) Text('${e.name}: \$${e.amount.toStringAsFixed(2)}'),
            const SizedBox(height: 16),
            Text('Total: \$${total.toStringAsFixed(2)}', style: const TextStyle(fontSize: 28)),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  expenses.add(Expense(name: 'Snack', amount: 2.25));
                });
              },
              child: const Text('Add a snack'),
            ),
          ],
        ),
      ),
    );
  }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

状態管理のすべてのレッスン

自分で練習してみよう: Flutterオンラインコンパイラ