Reducing a stream means taking many pieces of data that come from the stream and combining them into one single value. Imagine you have a list of numbers flowing one by one. Reducing lets you add them all up or join them into one string. It’s like gathering small parts to make a whole.
In Dart, you can reduce a stream to get results like the total of numbers, a combined sentence, or even a list of things. It helps turn many events into one final answer.
Using .reduce()
Method
The .reduce()
method helps you take many values from a stream and combine them into one single result. You give it a function that tells how to join two values at a time. The method works by applying this function repeatedly until only one value is left.
void main() {
Stream<int>.fromIterable([1, 2, 3, 4])
.reduce((a, b) => a + b)
.then((sum) => print('Sum: $sum'));
}
In this example, the stream sends the numbers 1, 2, 3, and 4 one by one. The .reduce()
method adds the first two numbers (1 + 2 = 3), then adds the next number to the result (3 + 3 = 6), and finally adds the last number (6 + 4 = 10). After all numbers are combined, the final sum is printed as “Sum: 10”. This shows how .reduce()
can combine many values from a stream into one.
Reducing with Strings
You can use .reduce()
to combine strings from a stream into one full sentence. The method joins each string with a space (or anything you like) between them.
void main() {
Stream<String>.fromIterable(['Dart', 'is', 'fun'])
.reduce((a, b) => '$a $b')
.then((sentence) => print(sentence));
}
In this example, the stream sends the words 'Dart'
, 'is'
, and 'fun'
one by one. The .reduce()
method joins 'Dart'
and 'is'
to make 'Dart is'
, then adds 'fun'
to make 'Dart is fun'
. Finally, it prints the full sentence. This shows how you can join strings from a stream easily using .reduce()
.
Using .fold()
for Custom Start Value
The .fold()
method lets you start with your own initial value, unlike .reduce()
which uses the first stream item as a start. This is helpful when you want to build something more complex from the stream data.
void main() {
Stream<int>.fromIterable([1, 2, 3])
.fold<List<int>>([], (list, n) {
list.add(n * n);
return list;
})
.then((squares) => print('Squares: $squares'));
}
In this example, .fold()
starts with an empty list []
. For each number from the stream, it calculates the square and adds it to the list. After the stream finishes, it prints the list of squares [1, 4, 9]
. This shows how .fold()
can collect results step by step with a custom starting value.
Fun Example: Combine Emojis
This example shows how to use .reduce()
to join emojis into one string.
void main() {
Stream<String>.fromIterable(['⭐', '🌙', '⭐'])
.reduce((a, b) => a + b)
.then((result) => print('Combined emojis: $result'));
}
Here, the stream sends three emojis one by one. The .reduce()
method takes two emojis at a time and joins them into one string. At the end, the program prints the combined string: ⭐🌙⭐. This is a fun way to see how reducing can merge many pieces into one.
Using .fold()
with Different Data Types
The .fold()
method can work with any type of data, like numbers, lists, or even counting things.
void main() {
Stream<int>.fromIterable([1, 2, 3, 4, 5, 6])
.fold<int>(0, (count, n) => n.isEven ? count + 1 : count)
.then((evenCount) => print('Even numbers count: $evenCount'));
}
In this example, we start counting from zero. For each number in the stream, .fold()
checks if it is even. If yes, it adds one to the count. Finally, it prints how many even numbers were found in the stream. This shows how .fold()
can build results from different types of data.
Combining .map()
and .reduce()
You can use .map()
to change the data in a stream before combining it with .reduce()
.
void main() {
Stream<int>.fromIterable([1, 2, 3])
.map((n) => n * 2)
.reduce((a, b) => a + b)
.then((sum) => print('Sum of doubles: $sum'));
}
Here, the .map()
doubles each number from the stream. After that, .reduce()
adds all the doubled numbers together. The final result is the sum of all the doubled numbers.
Real World Use: Total Sales Calculator
You can use .reduce()
to add up prices from a stream to get the total sales amount.
void main() {
Stream<double>.fromIterable([5.99, 10.50, 3.75])
.reduce((a, b) => a + b)
.then((total) => print('Total sales: \$${total.toStringAsFixed(2)}'));
}
This code takes a stream of prices and adds them all together using .reduce()
. The final total is printed with two decimal places, showing the total sales amount clearly.
Conclusion
Reducing streams means combining all the events from a stream into one single value. This lets you take many pieces of data and turn them into one result.
You can use .reduce()
when you want to combine values in a simple way. If you need to start with your own initial value, use .fold()
. Both methods help you work with streams easily.
Try reducing different types of data like numbers, strings, or lists. This will help you understand how to use .reduce()
and .fold()
in real situations.