If you are using Dart and you want to create a Map and initialize its value, you can read this tutorial.
Map is a data type for storing key value pairs. Map is usually used because of its fast search performance. Dart supports this data type. In this tutorial, I am going to show you how to create a Map in Dart using different ways including how to initialize values when creating a Map.
Define Initial Elements
You can create a new Map in Dart by using curly brackets with the initial elements put between the brackets. Each element is separated by comma. An element consists of a key and a value with :
as the separator.
Map<int, String> values = {
1: 'one',
2: 'two',
3: 'three',
};
If you use any keyword like var
, final
, or const
instead of specifying the variable type, you can define the Map type by adding <KeyType, ValueType>
before the curly brackets.
var values = <int, String>{
1: 'one',
2: 'two',
3: 'three',
};
Create From Existing Map/Iterable
Dart also has some methods that allow you to create a Map from an existing Map or Iterable.
Using Map.of
Map.of
can be used to create a new Map from an existing one.
factory Map.of(Map<K, V> other)
Example:
var values = <int, String>{
1: 'one',
2: 'two',
3: 'three',
};
var newValues = Map.of(values);
Using Map.from
This method is similar to Map.of
, but the key and/or element type of the new Map can be a subtype of the source key and/or element type. Therefore, it can be used to create a new Map with more precise types. When using Map.from
, you have to make sure that all the keys and values of the source have the more precise types as defined on the new Map.
factory Map.from(Map other)
Example:
var values = <num, String>{
1: 'one',
2: 'two',
3: 'three',
};
Map<int, String> newValues = Map.from(values);
Using Map.fromEntries
If you have an Iterable of MapEntry
, you can create a new Map using Map.fromEntries
factory method.
factory Map.fromEntries(Iterable<MapEntry<K, V>> entries)
Example:
List<MapEntry<int, String>> mapEntries = [
MapEntry(1, 'One'),
MapEntry(2, 'Two'),
MapEntry(3, 'Three'),
];
var values = Map.fromEntries(mapEntries);
Using Map.unmodifiable
This method allows you to create a new unmodifiable Map from an existing one.
factory Map.unmodifiable(Map<dynamic, dynamic> other)
Example:
var types = Map.unmodifiable({
1: 'one',
2: 'two',
3: 'three',
});
Using Map.castFrom
Map.castFrom
can be used to create a new Map variable whose key and/or value type is a supertype of the existing key and/or value type. It doesn't copy the source, but only produces a variable that refers to the same Map, with casted element type. If you remove or add an element to the source or the new variable, it will also affect the other one since basically they refer to the same Map.
static Map<K2, V2> castFrom<K, V, K2, V2>(Map<K, V> source)
For example, we have Animal
class and another class Cow
that extends Animal
.
class Animal {
String name;
Animal({
required this.name,
});
}
class Cow extends Animal {
double power;
Cow({
name,
required this.power,
}) : super(name: name);
}
If there is a Map whose element value type is Cow
, you can create a new Map variable whose element value type is Animal
. It works because a Cow
instance is also an Animal
instance. The same also applies for the element key type.
// // Below works
Map<int, Cow> cows = {1: Cow(name: 'Peeko', power: 100), 2: Cow(name: 'Bigfoot', power: 200)};
Map<int, Animal> animals = Map.castFrom(cows);
print(animals[1]);
However, the other way may throw an error when an element is accessed. That's because an Animal
object is not an instance of Cow
.
// Below doesn't work
Map<int, Animal> animals = {1: Animal(name: 'Peeko'), 2: Animal(name: 'Bigfoot')};
Map<int, Cow> cows = Map.castFrom(animals);
print(cows[1]); // throw type 'Animal' is not a subtype of type 'Cow?' in type cast
Using Map.fromIterables
If you have an Iterable that contains the keys and another Iterable that contains the values, you can create a new Map using Map.fromIterables factory method.
factory Map.fromIterables(Iterable<K> keys, Iterable<V> values)
Example:
List<int> keys = [1, 2, 3];
List<String> values = ['one', 'two', 'three'];
var newMap = Map.fromIterables(keys, values);
print(newMap);
You have to make sure that both Iterables have the same length. Otherwise you will get the following error.
Invalid argument(s): Iterables do not have same length.
Using Map.fromIterable
You can create a new Map from an Iterable by using Map.fromIterable
factory method.
factory Map.fromIterable(
Iterable iterable,
{K key(dynamic element)?,
V value(dynamic element)?}
)
There is one required argument where you have to pass an Iterable source. In addition, there are two optional named arguments key
and value
where you can pass custom functions to generate the key and the value respectively.
The example below only passes the Iterable without the optional arguments. As a result, the Map's keys and values are the same as the element values.
List<int> values = [1, 2, 3];
var newMap = Map.fromIterable(values);
print(newMap); // {1: 1, 2: 2, 3: 3}
Below is another example that passes functions for generating the keys and the values.
List<int> values = [1, 2, 3];
var newMap = Map.fromIterable(values, key: (e) => e * 10, value: (e) => e * 100);
print(newMap); // {10: 100, 20: 200, 30: 300}
Using For Loop
It's also possible to generate a Map from an Iterable using for loop where each loop returns the key and the value.
The example below is an alternative of the previous example that uses Map.fromIterable
.
List<int> values = [1, 2, 3];
var newMap = { for (var e in values) e * 10 : e * 100 };
print(newMap); // {10: 100, 20: 200, 30: 300}
Summary
There are several ways to create a Map in Dart. The most basic way to define is by using curly brackets where you can put the initial key-value pairs within the brackets. You can also create a Map by copying from an existing Map or Iterable. If the element type is mutable, you have to be careful as modifying an element of the source/original can affect the other. It's recommended to read our tutorial about how to perform deep copy and shallow copy on a Map in Dart.