Dart/Flutter Map Tutorial – Create/Add/Delete/Iterate/Sorting
Tags: dart, flutter, dartmap
Published: 2021-03-01 11:59:15

Dart Map Flutter Tutorial.

In the tutorial, I will introduce how to work wiht Dart Map by example coding. What will we do?

https://loizenai.com/dart-map-tutorial/
https://grokonez.com/dart-map-tutorial/

- How to Initial Dart Map by literal or constructor?
- Add new entry with Dart Map
- Iterate through Dart Map
- Update a Dart Map
- Delete with Dart Map
- Convert Dart Map to List
- Sorting a Dart Map

A collection of key/value pairs, from which you retrieve a value using its associated key.
Keys and values in a map may be of any type. A Map is a dynamic collection. Maps, and their keys and values, can be iterated.

Implementers
- HashMap, HttpSession, LinkedHashMap, MapMixin, MapView

<h2>Dart Map Literals</h2>
To declare a map using map literals, you need to enclose the key-value pairs within a pair of curly brackets "{ }".

Here is its syntax:

<pre><code>
var identifier = { key1:value1, key2:value2 [,…..,key_n:value_n] }
</code></pre>

Example:

<pre><code class="language-javascript">void main() { 
   var userInfo = {'Username':'Jack','Password':'123@passloizenai'}; 
   print(userInfo); 
}</code></pre>

output −

<pre><code class="language-javascript">{Username: Jack, Password: 123@passloizenai}
</code></pre>
<h2>Dart Map&lt;K, V&gt;() constructor</h2>
Creates a Map instance with the default implementation, LinkedHashMap.
This constructor is equivalent to the non-const map literal &lg;K,V&gt;{}.

A LinkedHashMap requires the keys to implement compatible operator<code>==</code> and hashCode, and it allows null as a key. It iterates in key insertion order.

Example:

<pre><code class="language-javascript">
void main() { 
   var userInfo = new Map(); 
   userInfo['Username'] = 'Jack'; 
   userInfo['Password'] = 'loizenai_password'; 
   print(details); 
} 
</code></pre>

Output :

<pre><code class="language-javascript">{Username: Jack, Password: loizenai_password}</code></pre>
<h2>Dart Map&lg;K, V&gt;.from constructor</h2>
<pre><code class="language-javascript">
Map&lt;K, V&gt;.from(
Map other
)
</code></pre>

Creates a LinkedHashMap instance that contains all key/value pairs of other.

The keys must all be instances of K and the values of V. The other map itself can have any type.
A LinkedHashMap requires the keys to implement compatible operator== and hashCode, and it allows null as a key. It iterates in key insertion order.

Example:

<pre><code class="language-javascript">
Map<String, int> userinfo = {'username': 'Jack', 'password': '123@loizenai'};

Map _userinfo = Map.from(userinfo);
print(_userinfo);
</code></pre>

Output:

<pre><code class="language-javascript">{_username: Jack, Password: 123@loizenai}</code></pre>
<h2>Dart Map&lt;K, V&gt;.of constructor</h2>
<pre><code class="language-javascript">Map&lt;K, V&gt;.of(
Map&lt;K, V&lt; other
)
</code></pre>

Creates a LinkedHashMap with the same keys and values as other.

A LinkedHashMap requires the keys to implement compatible operator== and hashCode, and it allows null as a key. It iterates in key insertion order.

Example:

<pre><code class="language-javascript">
Map<String, int> userinfo = {'username': 'Jack', 'password': '123@loizenai'};

Map _userinfo = Map.of(userinfo);
print(_userinfo);
</code></pre>

Output:

<pre><code class="language-javascript">{_username: Jack, Password: 123@loizenai}</code></pre>
<h2>Map&lt;K, V&gt;.fromIterable constructor</h2>
<pre><code class="language-javascript">Map<K, V>.fromIterable(
Iterable iterable,
	{
		K key(
			dynamic element
		),
		V value(
			dynamic element
		)
	}
)</code></pre>

Creates a Map instance in which the keys and values are computed from the iterable.

The created map is a LinkedHashMap. A LinkedHashMap requires the keys to implement compatible operator== and hashCode, and it allows null as a key. It iterates in key insertion order.

For each element of the iterable this constructor computes a key/value pair, by applying key and value respectively.

The example below creates a new Map from a List. The keys of map are list values converted to strings, and the values of the map are the squares of the list values:

<pre><code>List&lt;int&gt; list = [1, 2, 3];
Map&lt;String, int&gt; map = new Map.fromIterable(list,
    key: (item) =&gt; item.toString(),
    value: (item) =&gt; item * item);

map['1'] + map['2']; // 1 + 4
map['3'] - map['2']; // 9 - 4</code></pre>

If no values are specified for key and value the default is the identity function.

In the following example, the keys and corresponding values of map are list values:

<pre><code class="language-javascript">
map = new Map.fromIterable(list);
map[1] + map[2]; // 1 + 2
map[3] - map[2]; // 3 - 2
</code></pre>

The keys computed by the source iterable do not need to be unique. The last occurrence of a key will simply overwrite any previous value.
<h2>Dart Map&lt;K, V&gt;.fromIterables constructor</h2>
<pre><code class="language-javascript">
Map&lt;K, V&gt;.fromIterables(
	Iterable&lt;K&gt; keys,
	Iterable&lt;V&gt; values
)</code></pre>

Creates a Map instance associating the given keys to values.

The created map is a LinkedHashMap. A LinkedHashMap requires the keys to implement compatible operator== and hashCode, and it allows null as a key. It iterates in key insertion order.

This constructor iterates over keys and values and maps each element of keys to the corresponding element of values.

<pre><code class="language-javascript">List<String> letters = ['b', 'c'];
List&lt;String&gt; words = ['bad', 'cat'];
Map&lt;String, String&gt; map = new Map.fromIterables(letters, words);
map['b'] + map['c'];  // badcat</code></pre>

If keys contains the same object multiple times, the last occurrence overwrites the previous value.

The two Iterables must have the same length.
<h2>Map&lt;K, V&gt;.fromEntries constructor</h2>
<pre><code>Map&lt;K, V&gt;.fromEntries(
	Iterable&lt;MapEntry&lt;K, V&gt;&gt; entries
)</code></pre>

Creates a new map and adds all entries.
Returns a new Map<K, V> where all entries of entries have been added in iteration order. If multiple entries have the same key, later occurrences overwrite the earlier ones.

Example:

<pre><code class="language-javascript">
Iterable<int> someInts = [2, 7, .... ];
var squareMap = Map.fromEntries(someInts.map((n) =&lt; MapEntry(n, n * n)));
print(squareMap[7]);  // prints 49.
</code></pre>

Or you can filter the entries somehow:

<pre><code class="language-javascript">
var filteredMap = Map.fromEntries(otherMap.entries.where((e) =&lt; e.key.isOdd));
</code></pre>
<h2>Map&lt;K, V&gt;.identity constructor</h2>
Creates an identity map with the default implementation, LinkedHashMap.

An identity map uses identical for equality and identityHashCode for hash codes of keys instead of the intrinsic Object.== and Object.hashCode of the keys.

The returned map allows null as a key. It iterates in key insertion order.
<h2>Map&lt;K, V&gt;.unmodifiable constructor</h2>
<pre><code class="language-javascript">Map&lt;K, V&gt;.unmodifiable(
Map other
)</code></pre>

Creates an unmodifiable hash based map containing the entries of other.

The keys must all be instances of K and the values of V. The other map itself can have any type.

The map requires the keys to implement compatible operator== and hashCode, and it allows null as a key. The created map iterates keys in a fixed order, preserving the order provided by other.

The resulting map behaves like the result of Map.from, except that the map returned by this constructor is not modifiable.

Example:

<pre><code class="language-javascript">
Map map = Map.unmodifiable({1: 'one', 2: 'two'});
print(map);
// {1: one, 2: two}

map[3] = 'three';
</code></pre>

If you try to modify/add object to the unmodifiable Map, it will throw an error.

<pre><code class="language-javascript">Unhandled exception:
Unsupported operation: Cannot modify unmodifiable map</code></pre>
<h2>Difference between Map.from() and Map.of</h2>
See the example:

<pre><code class="language-javascript">Map&lt;int, String&gt; map = {1: 'one', 2: 'two'};

Map&ltString, String&gt map1 = Map.from(map); // runtime error
Map&ltString, String&gt map2 = Map.of(map);   // compilation error</code></pre>

– Map.from(map) doesn’t cause any compilation error. When we run the statement, the error occurs:

<pre><code class="language-javascript">Unhandled exception:
type 'int' is not a subtype of type 'String'</code></pre>

Why? -> This is because of its prototype:

<pre><code class="language-javascript">Map&lt;K, V&gt Map.from(Map&lt;dynamic, dynamic&gt; other)</code></pre>

If we pass a Map&lt;int, String&gt; map to the function, it converts the key-value pair type into Map&lt;dynamic, dynamic&gt;.

– Map.of(map) doesn’t do that thing, it keep the key-value pair type, so the compiler realizes the error before running the program.

Map&lt;K, V&gt; Map.of(Map&ltK, V&gt; other)
<h2 id="dart-map-get-value-by-key">Dart Map Get Value by Key</h2>
Example - What we do:

- Create a Dart Map:
- find the size of map.
- check if a Map is empty or not using .isEmpty or .isNotEmpty.
- get all keys or values with keys & values property.
- get value of specified key in a Map or operator [].

<pre><code class="language-javascript">
Map map = {1: 'one', 2: 'two'};

print(map.length);      // 2

print(map.isEmpty);     // false
print(map.isNotEmpty);  // true

print(map.keys);        // (1, 2)
print(map.values);      // (one, two)

print(map[2]);          // two
print(map[3]);          // null
</code></pre>
<h2 id=""dart-map-foreach>Dart Map Foreach</h2>
- forEach enables iterating through the Map’s entries.

<pre><code class="language-javascript">Map.forEach(void f(K key, V value));</code></pre>

- f(K key, V value) − Applies f to each key-value pair of the map.
Calling f must not add or remove keys from the map. Return Type − void.

Example:

<pre><code class="language-javascript">void main() { 
   var usrMap = {"name": "Jack", 'Email': 'jack@loizenai.com'}; 
   usrMap.forEach((k,v) =&gt; print('${k}: ${v}')); 
}</code></pre>

It will produce the following output −

<pre><code class="language-javascript">name: Jack
Email: jack@loizenai.com </code></pre>

We can use entries property and forEach() method.

<pre><code class="language-javascript">map.entries.forEach((e) {
  print('{ key: ${e.key}, value: ${e.value} }');
});</code></pre>

We can iterate over keys or values using Map property and forEach() method.:

<pre><code class="language-javascript">map.keys.forEach((k) => print(k));
map.values.forEach((v) => print(v));</code></pre>

Output:

<pre><code class="language-javascript">
name
Email
Jack
jack@loizenai.com
</code></pre>
<h2 id="dart-map-add">Dart Map Add</h2>
We have 2 way to add an item (key-value pair) to a Map:

- using square brackets []
- calling <code>putIfAbsent()</code> method

<pre><code class="language-javascript">Map map = {1: 'one', 2: 'two'};

map[3] = 'three';
print(map);

var threeValue = map.putIfAbsent(3, () => 'THREE');
print(map);
print(threeValue); // the value associated to key, if there is one

map.putIfAbsent(4, () => 'four');
print(map);</code></pre>

Output:

<pre><code class="language-javascript">{1: one, 2: two, 3: three}
{1: one, 2: two, 3: three}
three
{1: one, 2: two, 3: three, 4: four}</code></pre>

You can use <code>addAll()</code> method to all key/value pairs of another Map to current Map:

<pre><code class="language-javascript">Map map = {1: 'one', 2: 'two'};
map.addAll({3: 'three', 4: 'four', 5: 'five'});
print(map);</code></pre>

Output:

<pre><code class="language-javascript">{1: one, 2: two, 3: three, 4: four, 5: five}</code></pre>
<h2 id="dart-map-update">Dart Map Update</h2>
We use one of the below solution to update a Dart Map:

- square brackets []
- update() method
- update() method with ifAbsent to add a new object/entry if the input key is absent

Example Code:

<pre><code class="language-javascript">Map map = {1: 'one', 2: 'two'};

map[1] = 'ONE';
print(map);

map.update(2, (v) {
  print('old value: ' + v);
  return 'TWO';
});
print(map);

map.update(3, (v) => 'Three', ifAbsent: () => 'added');
print(map);</code></pre>

Output:

<pre><code class="language-javascript">{1: ONE, 2: two}
old value: two
{1: ONE, 2: TWO}
{1: ONE, 2: TWO, 3: added}</code></pre>
<h2>Remove Entry with Dart Map</h2>
<pre><code class="language-javascript">Map.remove(Object key)</code></pre>


Parameters:
	- Keys: identifies the entry to be deleted.
	- Return Type: Returns the value corresponding to the specified key.

Removes key and its associated value, if present, from the map.
Returns the value associated with key before it was removed. Returns null if key was not in the map.
Note that values can be null and a returned null value doesn't always mean that the key was absent.

Example:

<pre><code class="language-javascript">void main() { 
   Map m = {'name':'Tom','Id':'001'}; 
   print('Map :${m}'); 
   
   dynamic res = m.remove('name'); 
   print('Value popped from the Map :${res}'); 
}</code></pre>

- Output:

<pre><code class="language-javascript">Map :{name: Tom, Id: 001} 
Value popped from the Map :Tom</code></pre>

<h2 id="dart-sort-map-by-value">Dart Sort Map by Key</h2>
When we need to sort maps, we can use the SplayTreeMap. The SplayTreeMap is ordered by sorted keys.

<pre><code class="language-javascript">import 'dart:collection';

void main() {
  var fruit = new SplayTreeMap<int, String>();

  fruit[0] = 'Banana';
  fruit[5] = 'Plum';
  fruit[6] = 'Strawberry';
  fruit[2] = 'Orange';
  fruit[3] = 'Mango';
  fruit[4] = 'Blueberry';
  fruit[1] = 'Apple';

  print(fruit);

  fruit.forEach((key, val) {
    print('{ key: $key, value: $val}');
  });

  var sortedByValue = new SplayTreeMap<int, String>.from(
      fruit, (key1, key2) => fruit[key1].compareTo(fruit[key2]));
  print(sortedByValue);
}</code></pre>

- Output:

<pre><code class="language-javascript">{0: Banana, 1: Apple, 2: Orange, 3: Mango, 4: Blueberry, 5: Plum, 6: Strawberry}
{ key: 0, value: Banana}
{ key: 1, value: Apple}
{ key: 2, value: Orange}
{ key: 3, value: Mango}
{ key: 4, value: Blueberry}
{ key: 5, value: Plum}
{ key: 6, value: Strawberry}</code></pre>
<h2>Dart Convert Map to List</h2>
Create a Customer model:

<pre><code class="language-javascript">class Customer {
  String name;
  int age;

  Customer(this.name, this.age);

  @override
  String toString() {
    return '{ ${this.name}, ${this.age} }';
  }
}</code></pre>

Create a Dart Map:

<pre><code class="language-javascript">Map map = {'Jane': 21, 'Mary': 43, 'Peter': 13};</code></pre>

- Using Map <code>forEach()</code> method:

<pre><code class="language-javascript">map.forEach((k, v) => list.add(Customer(k, v)));
print(list);</code></pre>

Output:

<pre><code class="language-javascript">[{ Jane, 21 }, { Mary, 43 }, { Peter, 13 }]</code></pre>

- Using Iterable forEach() method:

<pre><code class="language-javascript">map.entries.forEach((e) => list.add(Customer(e.key, e.value)));
print(list);</code></pre>

- Using Iterable map() method:

<pre><code class="language-javascript">list = map.entries.map((e) => Customer(e.key, e.value)).toList();</code></pre>
<h2 id="dart-sort-map-by-value">Dart Sort Map by Value</h2>
Continue with above example, we create a sorted map by values from the original map. We pass the from function a comparison function, which compares the values of the pairs.

<pre><code class="language-javascript">var sortedByValue = new SplayTreeMap<int, String>.from(
    fruit, (key1, key2) => fruit[key1].compareTo(fruit[key2]));
	
print(sortedByValue);</code></pre>

- Output:

<pre><code class="language-javascript">{1: Apple, 0: Banana, 4: Blueberry, 3: Mango, 2: Orange, 5: Plum, 6: Strawberry}</code></pre>
<h2>Related posts</h2>
<div class="div-loizenai-pre-related-post">
Related posts:
<hr>
<ul class="ul-loizenai-pre-related-post">
<li><a href="https://loizenai.com/how-to-integrate-springboot-2-x-with-postgresql-database-using-spring-jpa/">Integrate SpringBoot with PostgreSQL using Spring JPA</a></li>
<li><a href="https://loizenai.com/kotlin-map-to-list-example/">Kotlin Map to List Example</a></li>
<li><a href="https://loizenai.com/java-read-write-csv-file-open-csv-apache-common/">Java Read Write CSV File Open CSV Apaceh Common</a></li>
<li><a href="https://loizenai.com/reactjs-crud-firebase-realtime-database/">Reactjs CRUD Firebase Realtime database</a></li>
<li><a href="https://loizenai.com/reactjs-crud-firestore-example/">Reactjs CRUD Firebase Example</a></li>
</ul>
</div>

Read more at <a href="https://api.dart.dev/stable/2.10.5/dart-core/Map-class.html">here</a>