In Dart, “mapping” a stream means changing the data that flows through it. You take each item in the stream and transform it into something else.
For example, you can take a stream of numbers like 1, 2, 3
and turn them into emojis like ⭐️, ⭐️⭐️, ⭐️⭐️⭐️
. This is done using the .map()
method.
Mapping is helpful when you want to change or format the data before using it in your app. Let’s look at how it works step by step.
Using .map()
to Change Stream Data
You can use the .map()
method on a stream to change each item before it reaches the listener. This is useful when you want to transform raw data into something more fun or meaningful.
void main() {
Stream<int>.fromIterable([1, 2, 3])
.map((number) => 'Dog #$number')
.listen((dog) => print(dog));
}
In this example, we create a stream using Stream<int>.fromIterable([1, 2, 3])
, which emits the numbers 1, 2, and 3 one by one. Then, we use the .map()
method to take each number and turn it into a string like "Dog #1"
, "Dog #2"
, and so on.
Finally, we use .listen()
to handle each transformed value and print it out. So, instead of printing numbers, we now print dog names. This is a fun and simple way to use .map()
in Dart streams.
Fun with .map()
: Emoji Converter
You can use .map()
to turn boring numbers into something more exciting—like emojis! This makes your stream data fun to read and easy to understand.
void main() {
Stream<int>.fromIterable([1, 2, 3])
.map((n) => '⭐️' * n)
.listen((stars) => print(stars));
}
In this example, we start with a stream of numbers: 1, 2, and 3. The .map()
function takes each number n
and turns it into a string made up of that many star emojis. So, 1
becomes '⭐️'
, 2
becomes '⭐️⭐️'
, and 3
becomes '⭐️⭐️⭐️'
.
The .listen()
part prints out each star string as it comes through the stream. It’s a magical way to turn plain data into something visual and fun.
Mapping Strings to Uppercase
You can also use .map()
to change how text looks. A common example is turning all letters into uppercase to make them louder or stand out more.
void main() {
Stream<String>.fromIterable(['hello', 'world'])
.map((word) => word.toUpperCase())
.listen((shout) => print(shout));
}
In this code, we have a stream of lowercase words: 'hello'
and 'world'
. The .map()
function takes each word and changes it using .toUpperCase()
. So 'hello'
becomes 'HELLO'
and 'world'
becomes 'WORLD'
.
The .listen()
part prints each uppercase word. It’s like giving your words a megaphone—perfect for names, titles, or attention-grabbing messages.
Mapping with Math
You can use .map()
to do simple math on each item in a stream. For example, you can double every number as it flows through the stream.
void main() {
Stream<int>.fromIterable([2, 4, 6])
.map((n) => n * 2)
.listen((result) => print('Doubled: $result'));
}
In this example, the stream starts with the numbers 2
, 4
, and 6
. Each number is passed to .map()
, where it is multiplied by 2
. So we get 4
, 8
, and 12
. The .listen()
part then prints each result with a small message. This is a fun and easy way to apply math to streaming data.
Mapping with Custom Classes
You can use .map()
to turn stream data into custom objects like classes. This is useful when you want to build richer data as your stream flows.
class Fish {
final int id;
Fish(this.id);
@override
String toString() => '🐟 Fish #$id';
}
void main() {
Stream<int>.fromIterable([1, 2, 3])
.map((id) => Fish(id))
.listen((fish) => print(fish));
}
In this example, we have a simple Fish
class that holds an ID. The stream gives us numbers from 1
to 3
. Using .map()
, each number is turned into a Fish
object. Then, the listen()
prints each fish using the custom toString()
method, so we see fun fish messages like “🐟 Fish #1”.
Chain Multiple .map()
Calls
You can use more than one .map()
on a stream to do multiple changes step by step. This keeps things clean and easy to read.
void main() {
Stream<int>.fromIterable([1, 2])
.map((n) => n * 3)
.map((n) => 'Triple: $n')
.listen((msg) => print(msg));
}
In this example, we start with a stream of numbers: 1
and 2
. First, each number is multiplied by 3. Then, the result is turned into a string that says “Triple: …”. The final output prints “Triple: 3” and “Triple: 6”. Each .map()
handles one small job, and together they build the final result.
Fun Game: Mapping Points to Levels
You can use .map()
to turn raw numbers like scores into more fun and useful values, like game levels.
void main() {
Stream<int>.fromIterable([100, 200, 300])
.map((score) => '🎮 Level ${score ~/ 100}')
.listen((level) => print(level));
}
In this example, we take a stream of scores: 100
, 200
, and 300
. Each score is divided by 100
using integer division (~/
) to find the level number. Then we turn it into a string like “🎮 Level 1”, “🎮 Level 2”, and so on. It’s a fun way to change scores into level messages.
Using .map()
with .where()
You can combine .where()
and .map()
to first filter data, then change it.
void main() {
Stream<int>.fromIterable([1, 2, 3, 4])
.where((n) => n.isEven)
.map((n) => n * 2)
.listen((value) => print('Even doubled: $value'));
}
In this code, we start with numbers 1, 2, 3, 4
. The .where()
filters only even numbers (2
and 4
). Then .map()
doubles those numbers, turning them into 4
and 8
. The program prints these doubled even numbers with the message “Even doubled:”. It shows how you can filter and then change values in a stream.
Conclusion
Mapping streams means changing or transforming the data inside them. You use .map()
to take each item and turn it into something new. It can be numbers, strings, emojis, or even objects.
With .map()
, streams become more fun and useful. You can mix .map()
with other methods like .where()
to filter and change data easily. Try playing with .map()
to see what cool things you can create!