Lesson 4
Compound Data Structures in C++
Introduction

Welcome to our exploration of Compound Data Structures in C++. Having navigated through basic data structures, we'll delve into nested maps and vectors. These structures enable us to handle complex and hierarchical data, which is typical in real-world scenarios. This lesson will guide you through a recap of the basics, the creation and modification of nested maps and vectors, as well as common operations.

Recap: Maps, Vectors, and Understanding Nested Structures

As a quick recap, std::vector is a dynamic array, while std::map is an associative container that stores key-value pairs. These structures can be nested. Here's a simple example of a school directory:

C++
1#include <iostream> 2#include <vector> 3#include <map> 4#include <string> 5 6int main() { 7 // Map with grades as keys and vectors of students as values 8 std::map<std::string, std::vector<std::string>> school_directory = { 9 {"Grade1", {"Amy", "Bobby", "Charlie"}}, 10 {"Grade2", {"David", "Eve", "Frank"}}, 11 {"Grade3", {"George", "Hannah", "Ivy"}} 12 }; 13 14 // Prints the Grade1 list in the map 15 for (const auto& student : school_directory["Grade1"]) { 16 std::cout << student << " "; 17 } // Output: Amy Bobby Charlie 18 19 return 0; 20}
Creating Nested Maps and Vectors

Just like their non-nested versions, creating nested structures is straightforward.

Nested Map:

C++
1#include <iostream> 2#include <map> 3#include <string> 4 5int main() { 6 // Map within a map 7 std::map<std::string, std::map<std::string, std::string>> nested_map = { 8 {"fruit", { 9 {"apple", "red"}, // key-value pair within the 'fruit' map 10 {"banana", "yellow"} // another key-value pair within the 'fruit' map 11 }}, 12 {"vegetable", { 13 {"carrot", "orange"}, 14 {"spinach", "green"} 15 }} 16 }; 17 18 // Prints the nested map 19 for (const auto& category : nested_map) { 20 std::cout << category.first << ": "; 21 for (const auto& item : category.second) { 22 std::cout << item.first << "(" << item.second << ") "; 23 } 24 std::cout << std::endl; 25 } 26 27 return 0; 28}

Nested Vector:

C++
1#include <iostream> 2#include <vector> 3 4int main() { 5 // Vectors within a vector 6 std::vector<std::vector<int>> nested_vector = { 7 {1, 2, 3}, // inner vector within the outer vector 8 {4, 5, 6}, // another inner vector within the outer vector 9 {7, 8, 9} // third inner vector within the outer vector 10 }; 11 12 // Prints the nested vector 13 for (const auto& vec : nested_vector) { 14 for (int val : vec) { 15 std::cout << val << " "; 16 } 17 std::cout << std::endl; 18 } 19 20 return 0; 21}

Nested Maps and Vectors:

C++
1#include <iostream> 2#include <map> 3#include <vector> 4#include <string> 5 6int main() { 7 // Vectors within a map 8 std::map<std::string, std::vector<int>> map_of_vectors = { 9 {"numbers", {1, 2, 3}}, // keys associated with vectors 10 {"more_numbers", {4, 5, 6}} 11 }; 12 13 // Prints the map of vectors 14 for (const auto& item : map_of_vectors) { 15 std::cout << item.first << ": "; 16 for (int val : item.second) { 17 std::cout << val << " "; 18 } 19 std::cout << std::endl; 20 } 21 22 return 0; 23}
Accessing Values in Nested Structures

The retrieval of values from nested maps or vectors follows rules similar to those for their non-nested counterparts.

From Nested Map:

C++
1#include <iostream> 2#include <map> 3#include <string> 4 5int main() { 6 // Map within a map 7 std::map<std::string, std::map<std::string, std::string>> nested_map = { 8 {"fruit", { 9 {"apple", "red"}, // key-value pair within the 'fruit' map 10 {"banana", "yellow"} // another key-value pair within the 'fruit' map 11 }}, 12 {"vegetable", { 13 {"carrot", "orange"}, 14 {"spinach", "green"} 15 }} 16 }; 17 18 // Accessing apple's color from nested map 19 std::cout << nested_map["fruit"]["apple"] << std::endl; // Output: red 20 21 return 0; 22}

From Nested Vector:

C++
1#include <iostream> 2#include <vector> 3 4int main() { 5 // Vectors within a vector 6 std::vector<std::vector<int>> nested_vector = { 7 {1, 2, 3}, // inner vector within the outer vector 8 {4, 5, 6}, // another inner vector within the outer vector 9 {7, 8, 9} // third inner vector within the outer vector 10 }; 11 12 // Accessing the 3rd value from the 2nd vector in nested vector 13 std::cout << nested_vector[1][2] << std::endl; // Output: 6 14 15 return 0; 16}

From Both:

C++
1#include <iostream> 2#include <map> 3#include <vector> 4#include <string> 5 6int main() { 7 // Vectors within a map 8 std::map<std::string, std::vector<int>> map_of_vectors = { 9 {"numbers", {1, 2, 3}}, // keys associated with vectors 10 {"more_numbers", {4, 5, 6}} 11 }; 12 13 // Accessing the second value from the 'numbers' vector in map_of_vectors 14 std::cout << map_of_vectors["numbers"][1] << std::endl; // Output: 2 15 16 return 0; 17}
Common Operations on these Structures

The modification of nested vectors and maps is similar to that of non-nested versions.

Operations on Nested Maps:

C++
1#include <iostream> 2#include <map> 3#include <string> 4 5int main() { 6 // Map within a map 7 std::map<std::string, std::map<std::string, std::string>> nested_map = { 8 {"fruit", { 9 {"apple", "red"}, 10 {"banana", "yellow"} 11 }}, 12 {"vegetable", { 13 {"carrot", "orange"}, 14 {"spinach", "green"} 15 }} 16 }; 17 18 // Modifying spinach's color to red 19 nested_map["vegetable"]["spinach"] = "red"; 20 21 // Adding cherry to the 'fruit' map in nested_map 22 nested_map["fruit"]["cherry"] = "red"; 23 24 // Deleting apple from the 'fruit' map in nested_map 25 nested_map["fruit"].erase("apple"); 26 27 return 0; 28}

Operations on Nested Vectors:

C++
1#include <iostream> 2#include <vector> 3 4int main() { 5 // Vectors within a vector 6 std::vector<std::vector<int>> nested_vector = { 7 {1, 2, 3}, 8 {4, 5, 6}, 9 {7, 8, 9} 10 }; 11 12 // Adding 10 to the first vector in nested vector 13 nested_vector[0].push_back(10); 14 15 // Deleting the 2nd value from the 3rd vector in nested vector 16 nested_vector[2].erase(nested_vector[2].begin() + 1); 17 18 return 0; 19}
Lesson Summary

Bravo! You've made a journey through nested vectors and maps, terms that are becoming increasingly common in the data-intensive programming world. We've learned how to create, access, and modify values in these complex structures.

Up next, we have hands-on practice sessions to solidify your understanding of these concepts. Hold on to your hats!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.