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つ追加され、次のビルドで新しいリストが合計されます。
チャレンジ
簡単合計の行は常に $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'),
),
],
),
),
);
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
状態管理のすべてのレッスン
自分で練習してみよう: Flutterオンラインコンパイラ