Skip to main content

Working with Maps

This guide explores practical map operations through real-world examples including phone directories and user profiles.

Basic Map Operations: Phone Directory

Let’s create a phone directory using a map:

Searching for Contacts

Check if a contact exists before accessing it:
Always use containsKey() to verify a key exists before accessing it to avoid null values.

Adding Contacts Dynamically

You can add new entries to a map after creation:

Iterating Through Maps

Use the forEach() method to iterate through all key-value pairs:
Output:
The forEach() method takes a function with two parameters: the key and the value.

Maps with Dynamic Values

Maps can store different types of values using the dynamic type:

Accessing Different Types

When using dynamic, Dart can’t check types at compile time. Be careful when accessing values to avoid runtime errors.

Iterating Dynamic Maps

Use forEach() with dynamic maps just like regular maps:
Output:

Complete Examples

Example 1: Phone Directory

Example 2: User Profile

Common Map Operations

Iteration Methods Comparison

Method 1: forEach()

Best for simple iteration:

Method 2: for-in with keys

When you need more control:

Method 3: entries

When you need both key and value as objects:

Use Cases for Different Map Types

String to String

Phone directories, translations, configuration settings

String to int

Ages, scores, quantities, IDs

String to dynamic

User profiles, JSON-like data, flexible configurations

int to String

Error codes to messages, ID to name mappings

Type Safety Considerations

Use strongly typed maps when all values are the same type for better type safety and IDE support.

Dynamic Maps (Use with Caution)

With dynamic maps, you lose compile-time type checking and need to cast values. Use only when necessary (e.g., JSON parsing).

Practical Patterns

Pattern 1: Safe Access with Default Value

Pattern 2: Conditional Update

Pattern 3: Bulk Operations

Pattern 4: Filter and Transform

Best Practices

  1. Use appropriate types: Choose Map<String, int> over Map<String, dynamic> when possible
  2. Check before access: Always use containsKey() or null-aware operators
  3. Use forEach() for iteration: It’s more concise and readable than manual loops
  4. Meaningful keys: Use descriptive key names that represent the data
  5. Handle null values: Maps return null for non-existent keys, so handle this appropriately
Remember: Map keys must be unique, but values can repeat. If you add an existing key, it will update the value, not create a duplicate.