In Dart, a Map is a collection of key-value pairs, where each key is unique, and it is associated with a value. Maps are commonly used when you need to associate data in a dictionary-like structure (e.g., storing user information where keys represent field names like name, age, etc.).
Type Declaration:
You can define the type of keys and values (e.g., Map<String, int>, Map<int, String>).
If the type is not specified, it defaults to Map<dynamic, dynamic>.
Map Literal:
Use curly braces {} to create a map with key-value pairs.
Map Constructor:
Use Map() or other constructors like Map.from(), Map.of(), Map.unmodifiable(), etc.
In Dart, a Map is a collection of key-value pairs, also known as a dictionary or associative array in other programming languages. Each key in a Map is unique, and it maps to a corresponding value. Maps are useful for storing and retrieving data in a key-based manner.
Here's a breakdown of Maps in Dart:
1. Creating Maps
Using Map literals: The most common way to create a map is using curly braces {} with key-value pairs separated by colons :.
var person = {
'name': 'John Doe',
'age': 30,
'city': 'New York',
};
var emptyMap = {}; // Creates an empty map
Using the Map constructor: You can also create a map using the Map constructor:
var productPrices = Map<String, double>(); // Creates an empty map with String keys and double values
var anotherWay = <String, int>{}; //another way to create an empty map with String keys and int values
2. Key Characteristics of Maps
Key-value pairs: Each element in a map consists of a key and its associated value.
Unique keys: Keys in a map must be unique. If you try to add a new key that already exists, the old value associated with that key will be overwritten.
Values can be duplicated: Values in a map can be duplicated. Multiple keys can map to the same value.
Unordered: Maps do not guarantee any specific order of elements.
3. Map Properties and Methods
Dart provides several methods to work with maps:
length: Returns the number of key-value pairs in the map.
keys: Returns an Iterable of all keys in the map.
values: Returns an Iterable of all values in the map.
containsKey(key): Checks if the map contains a specific key.
containsValue(value): Checks if the map contains a specific value.
putIfAbsent(key, ifAbsent): Adds a key-value pair to the map only if the key is not already present.
remove(key): Removes the key-value pair associated with the given key.
forEach(action): Executes a function for each key-value pair in the map.
clear(): Removes all key-value pairs from the map.
4. Accessing Values
You can access values in a map using their corresponding keys with the square bracket notation []:
main() {
var person = {
'name': 'John Doe',
'age': 30,
};
print(person['name']); // Output: John Doe
print(person['age']); // Output: 30
//If a key doesn't exist, it returns null
print(person['address']); // Output: null
}
When to use Maps:
Storing data with key-based access.
Representing objects or records with named fields.
Implementing caches or lookups.
Maps are a powerful and commonly used data structure in Dart for managing collections of key-value pairs, providing efficient access and manipulation of data.
void main() {
var productPrices = {
'apple': 1.0,
'banana': 0.5,
'orange': 0.75,
};
print(productPrices['banana']); // Output: 0.5
print(productPrices.length); // Output: 3
productPrices['grape'] = 2.0; // Add a new key-value pair
print(productPrices); // Output: {apple: 1.0, banana: 0.5, orange: 0.75, grape: 2.0}
productPrices.forEach((key, value) {
print('$key: \$$value');
});
if (productPrices.containsKey('apple')) {
print('Price of apple: \$${productPrices['apple']}');
}
productPrices.remove('banana');
print(productPrices); // Output: {apple: 1.0, orange: 0.75, grape: 2.0}
print(productPrices.keys); // Output: (apple, orange, grape)
print(productPrices.values); // Output: (1.0, 0.75, 2.0)
}
1. Empty Map
Use the Map constructor to create an empty map.
void main() {
Map<String, int> emptyMap = Map();
print(emptyMap); // Output: {}
}
2. Map with Initial Key-Value Pairs
Use a map literal to initialize a map.
void main() {
Map<String, String> capitals = {
'USA': 'Washington D.C.',
'India': 'New Delhi',
'Japan': 'Tokyo'
};
print(capitals); // Output: {USA: Washington D.C., India: New Delhi, Japan: Tokyo}
}
3. Dynamic Map
If no type is specified, keys and values can be of mixed types.
void main() {
Map<dynamic, dynamic> mixedMap = {1: 'One', 'Two': 2, true: 'Boolean'};
print(mixedMap); // Output: {1: One, Two: 2, true: Boolean}
}
4. Add Key-Value Pairs
Use the [] operator or .addAll() to add entries.
void main() {
Map<String, int> ages = {'Alice': 25};
ages['Bob'] = 30; // Add a new key-value pair
ages.addAll({'Charlie': 35, 'David': 40}); // Add multiple entries
print(ages); // Output: {Alice: 25, Bob: 30, Charlie: 35, David: 40}
}
5. Update Values
Update an existing value by assigning it a new value.
void main() {
Map<String, String> colors = {'Red': 'FF0000', 'Green': '00FF00'};
colors['Green'] = '008000'; // Update the value for the key 'Green'
print(colors); // Output: {Red: FF0000, Green: 008000}
}
6. Remove Key-Value Pairs
Use .remove() or .removeWhere() to delete entries.
void main() {
Map<String, int> items = {'Apple': 10, 'Banana': 20, 'Cherry': 30};
items.remove('Banana'); // Removes the key 'Banana'
print(items); // Output: {Apple: 10, Cherry: 30}
// Remove entries conditionally
items.removeWhere((key, value) => value > 20);
print(items); // Output: {Apple: 10}
}
7. Using Map.from()
Create a map by copying another map.
void main() {
Map<String, int> original = {'A': 1, 'B': 2};
Map<String, int> copy = Map.from(original);
print(copy); // Output: {A: 1, B: 2}
}
8. Using Map.of()
Create a map from another collection (e.g., a map or iterable of key-value pairs).
void main() {
Map<String, int> source = {'X': 10, 'Y': 20};
Map<String, int> newMap = Map.of(source);
print(newMap); // Output: {X: 10, Y: 20}
}
9. Unmodifiable Map
Create a read-only map using Map.unmodifiable().
void main() {
Map<String, int> readonlyMap = Map.unmodifiable({'One': 1, 'Two': 2});
print(readonlyMap); // Output: {One: 1, Two: 2}
// readonlyMap['Three'] = 3; // Error: Unsupported operation
}
10. Using Map.fromIterable()
Create a map from an iterable collection.
void main() {
List<String> fruits = ['Apple', 'Banana', 'Cherry'];
Map<String, int> fruitMap = Map.fromIterable(
fruits,
key: (item) => item,
value: (item) => item.length, // Use the length of each fruit as the value
);
print(fruitMap); // Output: {Apple: 5, Banana: 6, Cherry: 6}
}
Key-Value Pair Storage:
Each key is unique and associated with a value.
Example:
Map<String, int> scores = {'Math': 90, 'Science': 85};
print(scores['Math']); // Output: 90
void main() {
Map<String, int> scores = {'Alice': 90, 'Bob': 85, 'Charlie': 92};
// Using forEach
scores.forEach((key, value) {
print('$key: $value');
});
// Using a for-in loop
for (var entry in scores.entries) {
print('${entry.key}: ${entry.value}');
}
}
Keys are Unique:
Duplicate keys are not allowed. If you try to add a key that already exists, the value for that key will be updated.
Null Safety:
A map itself can be nullable (Map?), and keys or values can also be nullable if specified (Map<String?, int?>).
Flexible Initialization:
Maps can be initialized with literal syntax, from other collections, or using constructors.
Efficient Lookups:
Accessing a value by its key is fast and efficient.
void main() {
Map<String, int> ages = {'Alice': 25, 'Bob': 30, 'Charlie': 35};
print(ages);
}
void main() {
Map<String, String> capitals = {'USA': 'Washington D.C.', 'India': 'New Delhi', 'Japan': 'Tokyo'};
print('Capital of India: ${capitals['India']}');
}
void main() {
Map<String, String> languages = {'Python': 'Easy', 'Dart': 'Fun'};
languages['Java'] = 'Versatile';
print(languages);
}
void main() {
Map<String, int> scores = {'Math': 90, 'Science': 85};
scores['Science'] = 95; // Update Science score
print(scores);
}
void main() {
Map<String, int> products = {'Apple': 50, 'Banana': 30, 'Cherry': 40};
products.remove('Banana');
print(products);
}
void main() {
Map<String, int> stock = {'Laptops': 10, 'Mobiles': 20};
print(stock.containsKey('Laptops')); // true
print(stock.containsValue(15)); // false
}
void main() {
Map<String, String> countries = {'India': 'New Delhi', 'France': 'Paris', 'Italy': 'Rome'};
countries.forEach((key, value) {
print('$key: $value');
});
}
void main() {
Map<String, int> items = {'Pen': 5, 'Notebook': 20, 'Eraser': 2};
print('Keys: ${items.keys}');
print('Values: ${items.values}');
}
void main() {
Map<String, int> map1 = {'A': 1, 'B': 2};
Map<String, int> map2 = {'C': 3, 'D': 4};
Map<String, int> mergedMap = {...map1, ...map2};
print(mergedMap); // {A: 1, B: 2, C: 3, D: 4}
}
void main() {
Map<String, String> students = {'Alice': 'A', 'Bob': 'B', 'Charlie': 'A'};
print('Number of students: ${students.length}');
}
Here are ten Dart programs that demonstrate the use of Map collections. Each program showcases different functionalities such as adding, updating, accessing, sorting, and filtering key-value pairs in a map.
void main() {
Map<String, int> scores = {
"Alice": 90,
"Bob": 85,
"Charlie": 92,
};
// Add new key-value pair
scores["Diana"] = 88;
// Update existing key-value pair
scores["Bob"] = 95;
// Access a value
print("Alice's score: ${scores['Alice']}");
// Print the entire map
print("Scores: $scores");
}
void main() {
Map<String, String> countries = {
"USA": "Washington, D.C.",
"India": "New Delhi",
"Germany": "Berlin",
};
// Iterate using forEach
countries.forEach((country, capital) {
print("The capital of $country is $capital.");
});
}
void main() {
Map<String, String> fruits = {
"Apple": "Red",
"Banana": "Yellow",
"Grapes": "Green",
};
// Remove a key-value pair by key
fruits.remove("Banana");
print("Fruits after removal: $fruits");
}
void main() {
Map<String, int> inventory = {
"Apple": 50,
"Banana": 30,
"Orange": 20,
};
// Check if key exists
if (inventory.containsKey("Apple")) {
print("Apple is available in the inventory.");
}
// Check if value exists
if (inventory.containsValue(30)) {
print("There are 30 bananas in stock.");
}
}
void main() {
Map<String, int> ages = {
"Charlie": 25,
"Bob": 30,
"Alice": 20,
};
var sortedKeys = ages.keys.toList()..sort();
print("Sorted Map by Key:");
for (var key in sortedKeys) {
print("$key: ${ages[key]}");
}
}
void main() {
Map<String, int> grades = {
"Alice": 85,
"Bob": 95,
"Charlie": 75,
};
var sortedByValue = Map.fromEntries(
grades.entries.toList()..sort((e1, e2) => e2.value.compareTo(e1.value)),
);
print("Sorted Map by Value:");
sortedByValue.forEach((key, value) {
print("$key: $value");
});
}
void main() {
Map<String, int> map1 = {
"a": 1,
"b": 2,
};
Map<String, int> map2 = {
"c": 3,
"d": 4,
};
// Combine two maps
map1.addAll(map2);
print("Combined Map: $map1");
}
void main() {
Map<String, List<String>> students = {
"Alice": ["Math", "Science"],
"Bob": ["English", "History"],
};
// Adding new courses to Alice's list
students["Alice"]?.add("Art");
// Print courses of each student
students.forEach((name, courses) {
print("$name's courses: $courses");
});
}
void main() {
Map<String, int> fruits = {
"Apple": 5,
"Banana": 10,
};
// Set a default value if the key doesn't exist
fruits.putIfAbsent("Orange", () => 15);
fruits.putIfAbsent("Apple", () => 20); // Apple already exists
print("Fruits: $fruits");
}
void main() {
Map<String, int> items = {
"item1": 10,
"item2": 30,
"item3": 5,
"item4": 20,
};
// Filter out items where value is less than 15
Map<String, int> filteredItems = items
.where((key, value) => value >= 15)
.map((key, value) => MapEntry(key, value))
.toMap();
print("Filtered Items: $filteredItems");
}
Adding, updating, and removing key-value pairs.
Iterating over a map to access both keys and values.
Checking for the existence of a key or value.
Sorting a map by key or value.
Combining two maps into one.
Using lists as map values.
Setting default values with putIfAbsent.
Filtering a map based on conditions.
These examples show how versatile the Map collection can be in Dart for managing and manipulating key-value pairs