この記事は 2026 年 8 月 24 日に投稿しました。

目次
- はじめに
- DartのHashSetの要素をまとめて計算する
- foldメソッドの基本的な使い方
- 文字列を連結する
- 空のHashSetでfoldメソッドを使用した場合
- foldメソッドを使用する場合の注意点
- おわりに
1. はじめに
こんにちは、iOS のエディタアプリPWEditorとその後継PWEditorNextの開発者の二俣です。
2018年5月から毎日技術ブログを更新しています。
今回はDartのHashSetに格納された要素を順番に処理し、1つの値にまとめることができるfoldメソッドについてです。
2. DartのHashSetの要素をまとめて計算する
DartのHashSetでは、foldメソッドを使用すると、格納されているすべての要素を順番に処理し、最終的に1つの値へまとめることができます。
例えば、数値が格納されたHashSetの合計値を求める場合は、foldメソッドを使用できます。
foldメソッドの形式は以下になります。
T fold<T>( T initialValue, T combine(T previousValue, E element), )
第1引数には、計算を開始する初期値を指定します。
第2引数には、現在までの計算結果と、次に処理する要素を受け取る関数を指定します。
例えば、次のようなHashSetがあるとします。
final numbers = HashSet<int>(); numbers.addAll([ 10, 20, 30, ]);
このHashSetの合計値を求めるには、次のように記述します。
final result = numbers.fold(
0,
(sum, number) => sum + number,
);
print(result);
初期値は0です。
各要素を処理するたびに、それまでの合計値へ要素の値を加算します。
そのため、実行結果は以下のようになります。
60
実装例
import 'dart:collection'; void main() { final numbers = HashSet<int>(); numbers.addAll([ 10, 20, 30, ]); final result = numbers.fold( 0, (sum, number) => sum + number, ); print(result); }
この例では、次のように計算されます。
初期値: 0 0 + 10 = 10 10 + 20 = 30 30 + 30 = 60
最終的な計算結果である60が、foldメソッドの戻り値になります。
なお、HashSetでは要素の反復順序が保証されていません。
加算のように、処理する順序が変わっても結果が変わらない計算であれば問題ありません。
3. foldメソッドの基本的な使い方
foldメソッドでは、初期値と各要素を組み合わせて、累積した結果を作成します。
例えば、数値の積を求める場合は、初期値に1を指定します。
import 'dart:collection'; void main() { final numbers = HashSet<int>(); numbers.addAll([ 2, 3, 4, ]); final result = numbers.fold( 1, (total, number) => total * number, ); print(result); }
実行結果は以下になります。
24
合計を求める場合は0、積を求める場合は1を初期値に指定するのが一般的です。
また、foldメソッドでは、要素の型と戻り値の型を異なるものにすることもできます。
final numbers = HashSet<int>(); numbers.addAll([ 10, 20, 30, ]); final result = numbers.fold<String>( '', (text, number) => '$text$number ', ); print(result);
この場合、戻り値の型はStringです。
実行結果は、HashSetの順序によって異なる可能性があります。
4. 文字列を連結する
文字列を格納したHashSetに対して、foldメソッドを使用することもできます。
import 'dart:collection'; void main() { final languages = HashSet<String>(); languages.addAll([ 'Dart', 'Flutter', 'Swift', ]); final result = languages.fold<String>( '', (text, language) { if (text.isEmpty) { return language; } return '$text, $language'; }, ); print(result); }
単純に要素を連結するだけであれば、foldメソッドよりもjoinメソッドの方が簡潔に記述できます。
final result = languages.join(', '); print(result);
foldメソッドは、文字列の長さの合計など、要素とは異なる型の値へまとめる場合にも利用できます。
final result = languages.fold<int>( 0, (total, language) => total + language.length, ); print(result);
5. 空のHashSetでfoldメソッドを使用した場合
空のHashSetに対してfoldメソッドを使用した場合、初期値がそのまま戻り値になります。
import 'dart:collection'; void main() { final numbers = HashSet<int>(); final result = numbers.fold( 0, (sum, number) => sum + number, ); print(result); }
numbersには要素が1つもないため、結合処理は実行されません。
そのため、初期値である0がそのまま返されます。
0
foldメソッドは、初期値を指定できるため、空のHashSetでも例外が発生しません。
一方、reduceメソッドでは、空のコレクションに対して実行すると例外が発生します。
空の可能性があるコレクションを安全に処理したい場合は、foldメソッドが適しています。
6. foldメソッドを使用する場合の注意点
HashSetでfoldメソッドを使用する場合、要素の順序が保証されていない点に注意が必要です。
例えば、減算や除算、文字列の連結など、処理順序によって結果が変わる処理では注意してください。
順序を保証したい場合は、ListやLinkedHashSetなどを使用する必要があります。
また、foldメソッドの結合関数では、前回の結果を適切に返す必要があります。
final result = numbers.fold( 0, (sum, number) { final next = sum + number; return next; }, );
処理が1つだけであれば、アロー構文を使用できます。
final result = numbers.fold(
0,
(sum, number) => sum + number,
);
foldとreduceの違い
| メソッド | 初期値 | 空のHashSet |
|---|---|---|
| fold | 指定できる | 初期値を返す |
| reduce | 指定できない | 例外が発生する |
例えば、reduceメソッドでは、最初の要素を初期値として使用します。
final result = numbers.reduce(
(sum, number) => sum + number,
);
一方、foldメソッドでは、初期値を明示的に指定します。
final result = numbers.fold(
0,
(sum, number) => sum + number,
);
なお、foldメソッドはHashSet固有のメソッドではありません。
HashSetはIterableとして扱えるため、Iterableで定義されているfoldメソッドを利用できます。
リファレンス
6. おわりに
DartのHashSetに格納された要素を1つの値へまとめるには、foldメソッドを使用します。
例えば、数値の合計を求める場合は、次のように記述できます。
final numbers = HashSet<int>(); numbers.addAll([ 10, 20, 30, ]); final result = numbers.fold( 0, (sum, number) => sum + number, );
この場合、10 + 20 + 30が計算されるため、結果は60になります。
foldメソッドは初期値を指定できるため、空のHashSetに対しても安全に使用できます。
また、数値の合計だけでなく、積の計算、文字列の連結、文字列の長さの合計など、さまざまな処理に利用できます。
一方、HashSetは要素の順序を保証しないため、順序によって結果が変わる処理を行う場合は注意が必要です。
複数の要素を順番に処理して、最終的に1つの値へまとめたい場合に、foldメソッドを利用できます。
私が技術者として所属している ニューラル では、 組み込み・制御系ソフトウェアを中心に、モバイルアプリや業務アプリなど、さまざまなソフトウェアの開発を行っています。
組み込み分野では、リアルタイムOSを利用したシステム開発をはじめ、弊社製品のハイブリッドOS Bi-OS など、長年培ってきた組み込み・制御系の技術を活かした開発に取り組んでいます。
また、iOS(Swift/SwiftUI)やWindows(C#)をはじめとしたアプリケーション開発、Webシステムの開発などにも対応しています。
組み込みソフトウェア、モバイルアプリ、Windowsアプリ、Webシステムなど、ソフトウェア開発に関するご相談がございましたら、お気軽にお問い合わせください。
また、ニューラルでは一緒にソフトウェア開発に取り組んでいただける技術者の方も募集しています。
ご興味がございましたら、お気軽にお問い合わせください。
EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688