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:

#include <iostream>
#include <vector>
#include <map>
#include <string>

int main() {
    // Map with grades as keys and vectors of students as values
    std::map<std::string, std::vector<std::string>> school_directory = {
        {"Grade1", {"Amy", "Bobby", "Charlie"}},
        {"Grade2", {"David", "Eve", "Frank"}},
        {"Grade3", {"George", "Hannah", "Ivy"}}
    };

    // Prints the Grade1 list in the map
    for (const auto& student : school_directory["Grade1"]) {
        std::cout << student << " ";
    } // Output: Amy Bobby Charlie 

    return 0;
}

Creating Nested Maps and Vectors

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

Nested Map:

#include <iostream>
#include <map>
#include <string>

int main() {
    // Map within a map
    std::map<std::string, std::map<std::string, std::string>> nested_map = {
        {"fruit", {
            {"apple", "red"}, // key-value pair within the 'fruit' map
            {"banana", "yellow"} // another key-value pair within the 'fruit' map
        }},
        {"vegetable", {
            {"carrot", "orange"},
            {"spinach", "green"}
        }}
    };

    // Prints the nested map
    for (const auto& category : nested_map) {
        std::cout << category.first << ": ";
        for (const auto& item : category.second) {
            std::cout << item.first << "(" << item.second << ") ";
        }
        std::cout << std::endl;
    }

    return 0;
}

Nested Vector:

#include <iostream>
#include <vector>

int main() {
    // Vectors within a vector
    std::vector<std::vector<int>> nested_vector = {
        {1, 2, 3}, // inner vector within the outer vector
        {4, 5, 6}, // another inner vector within the outer vector
        {7, 8, 9}  // third inner vector within the outer vector
    };

    // Prints the nested vector
    for (const auto& vec : nested_vector) {
        for (int val : vec) {
            std::cout << val << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

Nested Maps and Vectors:

#include <iostream>
#include <map>
#include <vector>
#include <string>

int main() {
    // Vectors within a map
    std::map<std::string, std::vector<int>> map_of_vectors = {
        {"numbers", {1, 2, 3}}, // keys associated with vectors
        {"more_numbers", {4, 5, 6}}
    };

    // Prints the map of vectors
    for (const auto& item : map_of_vectors) {
        std::cout << item.first << ": ";
        for (int val : item.second) {
            std::cout << val << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

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:

#include <iostream>
#include <map>
#include <string>

int main() {
    // Map within a map
    std::map<std::string, std::map<std::string, std::string>> nested_map = {
        {"fruit", {
            {"apple", "red"}, // key-value pair within the 'fruit' map
            {"banana", "yellow"} // another key-value pair within the 'fruit' map
        }},
        {"vegetable", {
            {"carrot", "orange"},
            {"spinach", "green"}
        }}
    };

    // Accessing apple's color from nested map
    std::cout << nested_map["fruit"]["apple"] << std::endl; // Output: red

    return 0;
}

From Nested Vector:

#include <iostream>
#include <vector>

int main() {
    // Vectors within a vector
    std::vector<std::vector<int>> nested_vector = {
        {1, 2, 3}, // inner vector within the outer vector
        {4, 5, 6}, // another inner vector within the outer vector
        {7, 8, 9}  // third inner vector within the outer vector
    };

    // Accessing the 3rd value from the 2nd vector in nested vector
    std::cout << nested_vector[1][2] << std::endl; // Output: 6

    return 0;
}

From Both:

#include <iostream>
#include <map>
#include <vector>
#include <string>

int main() {
    // Vectors within a map
    std::map<std::string, std::vector<int>> map_of_vectors = {
        {"numbers", {1, 2, 3}}, // keys associated with vectors
        {"more_numbers", {4, 5, 6}}
    };

    // Accessing the second value from the 'numbers' vector in map_of_vectors
    std::cout << map_of_vectors["numbers"][1] << std::endl; // Output: 2

    return 0;
}

Common Operations on these Structures

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

Operations on Nested Maps:

#include <iostream>
#include <map>
#include <string>

int main() {
    // Map within a map
    std::map<std::string, std::map<std::string, std::string>> nested_map = {
        {"fruit", {
            {"apple", "red"}, 
            {"banana", "yellow"}
        }},
        {"vegetable", {
            {"carrot", "orange"},
            {"spinach", "green"}
        }}
    };

    // Modifying spinach's color to red
    nested_map["vegetable"]["spinach"] = "red";

    // Adding cherry to the 'fruit' map in nested_map
    nested_map["fruit"]["cherry"] = "red";

    // Deleting apple from the 'fruit' map in nested_map
    nested_map["fruit"].erase("apple");

    return 0;
}

Operations on Nested Vectors:

#include <iostream>
#include <vector>

int main() {
    // Vectors within a vector
    std::vector<std::vector<int>> nested_vector = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    // Adding 10 to the first vector in nested vector
    nested_vector[0].push_back(10);

    // Deleting the 2nd value from the 3rd vector in nested vector
    nested_vector[2].erase(nested_vector[2].begin() + 1);

    return 0;
}

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!

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal