Maps in Dart

Maps are like dictionaries or phone books - they store data in key-value pairs where each key is unique and maps to a specific value. Think of it as a way to organize information where you can quickly look up a value using its corresponding key.

What is a Map?

A Map is a collection of key-value pairs where:

  • Each key is unique
  • Keys can be of any type (String, int, etc.)
  • Values can be of any type and don't need to be unique
  • Maps are unordered collections

Creating Maps

You can create maps in several ways:

Using Map Literal Syntax:

// String keys with String values
var studentGrades = {
  'Alice': 'A',
  'Bob': 'B+',
  'Charlie': 'A-'
};

// Mixed types
var userInfo = {
  'name': 'John',
  'age': 25,
  'isActive': true
};

// Empty map
var emptyMap = <String, int>{};

Using Map Constructor:

// Creating an empty map
var colors = Map<String, String>();

// Creating from another map
var originalMap = {'a': 1, 'b': 2};
var copiedMap = Map.from(originalMap);

Accessing Map Elements

You can access values using square brackets with the key:

var fruits = {
  'apple': 'red',
  'banana': 'yellow',
  'grape': 'purple'
};

print(fruits['apple']);    // Output: red
print(fruits['banana']);   // Output: yellow
print(fruits['orange']);   // Output: null (key doesn't exist)

Adding and Updating Elements

var inventory = <String, int>{};

// Adding new elements
inventory['apples'] = 50;
inventory['oranges'] = 30;

// Updating existing elements
inventory['apples'] = 45;

print(inventory); // {apples: 45, oranges: 30}

Useful Map Properties and Methods

Property/MethodDescriptionExample
lengthReturns number of key-value pairsmap.length
isEmptyChecks if map is emptymap.isEmpty
isNotEmptyChecks if map is not emptymap.isNotEmpty
keysReturns all keysmap.keys
valuesReturns all valuesmap.values
containsKey()Checks if key existsmap.containsKey('key')
containsValue()Checks if value existsmap.containsValue('value')
remove()Removes key-value pairmap.remove('key')
clear()Removes all elementsmap.clear()

Working with Map Methods

var bookPrices = {
  'Dart Guide': 29.99,
  'Flutter Basics': 34.99,
  'Mobile Development': 39.99
};

// Check if a book exists
if (bookPrices.containsKey('Dart Guide')) {
  print('Dart Guide costs \$${bookPrices['Dart Guide']}');
}

// Get all book titles
print('Available books: ${bookPrices.keys.toList()}');

// Get all prices
print('Prices: ${bookPrices.values.toList()}');

// Remove a book
bookPrices.remove('Flutter Basics');
print('After removal: $bookPrices');

Iterating Through Maps

You can loop through maps in different ways:

var cityPopulations = {
  'New York': 8419000,
  'Los Angeles': 3980000,
  'Chicago': 2716000
};

// Iterate through key-value pairs
cityPopulations.forEach((city, population) {
  print('$city has $population people');
});

// Iterate through keys only
for (var city in cityPopulations.keys) {
  print('City: $city');
}

// Iterate through values only
for (var population in cityPopulations.values) {
  print('Population: $population');
}

Practical Example: Student Management

// Student management system
var students = <String, Map<String, dynamic>>{};

// Adding student information
students['S001'] = {
  'name': 'Alice Johnson',
  'grade': 'A',
  'subjects': ['Math', 'Science', 'English']
};

students['S002'] = {
  'name': 'Bob Smith',
  'grade': 'B+',
  'subjects': ['History', 'Art', 'Math']
};

// Accessing nested information
print('Student S001: ${students['S001']!['name']}');
print('Grade: ${students['S001']!['grade']}');

// Check if student exists
if (students.containsKey('S003')) {
  print('Student found');
} else {
  print('Student not found');
}

Maps are incredibly useful for organizing related data and creating efficient lookup systems. They're perfect when you need to associate unique identifiers with specific information!