Introduction

Welcome to our exploration of Compound Data Structures in Go. With a foundation in basic data structures like slices and maps, we'll delve into their nested use. 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 slices, as well as common operations.

Recap: Maps, Slices, and Understanding Nested Structures

As a quick recap, slices in Go are flexible, dynamic arrays, while maps provide a way to store key-value pairs efficiently. Both can be nested to manage hierarchical data. Here's a simple example of a school directory using maps and slices:

package main

import (
    "fmt"
)

func main() {
    // Map with grades (int) as keys and slices of students (strings) as values
    schoolDirectory := map[int][]string{
        1: {"Amy", "Bobby", "Charlie"},
        2: {"David", "Eve", "Frank"},
        3: {"George", "Hannah", "Ivy"},
    }

    // Prints the Grade1 list in the map
    for _, student := range schoolDirectory[1] {
        fmt.Print(student, " ")
    }
    // Output: Amy Bobby Charlie
}
Creating Nested Maps and Slices

Creating nested structures in Go is straightforward, thanks to the language's versatile nature.

Nested Map:

package main

import (
    "fmt"
)

func main() {
    // Map within a map
    nestedMap := map[string]map[string]string{
        "fruit": {
            "apple":  "red",
            "banana": "yellow",
        },
        "vegetable": {
            "carrot":  "orange",
            "spinach": "green",
        },
    }

    // Prints the nested map
    for category, items := range nestedMap {
        fmt.Print(category, ": ")
        for item, color := range items {
            fmt.Print(item, "(", color, ") ")
        }
        fmt.Println()
    }
}

Nested Slice:

package main

import (
    "fmt"
)

func main() {
    // Slices within a slice
    nestedSlice := [][]int{
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9},
    }

    // Prints the nested slice
    for _, slice := range nestedSlice {
        for _, val := range slice {
            fmt.Print(val, " ")
        }
        fmt.Println()
    }
}

Nested Maps and Slices:

package main

import (
    "fmt"
)

func main() {
    // Slices within a map
    mapOfSlices := map[string][]int{
        "numbers":      {1, 2, 3},
        "more_numbers": {4, 5, 6},
    }

    // Prints the map of slices
    for key, slice := range mapOfSlices {
        fmt.Print(key, ": ")
        for _, val := range slice {
            fmt.Print(val, " ")
        }
        fmt.Println()
    }
}
Accessing Values in Nested Structures

Accessing values from nested maps or slices in Go follows similar principles as their non-nested counterparts.

From Nested Map:

package main

import (
    "fmt"
)

func main() {
    // Map within a map
    nestedMap := map[string]map[string]string{
        "fruit": {
            "apple":  "red",
            "banana": "yellow",
        },
        "vegetable": {
            "carrot":  "orange",
            "spinach": "green",
        },
    }

    // Accessing apple's color from nested map
    fmt.Println(nestedMap["fruit"]["apple"]) // Output: red
}

From Nested Slice:

package main

import (
    "fmt"
)

func main() {
    // Slices within a slice
    nestedSlice := [][]int{
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9},
    }

    // Accessing the 3rd value from the 2nd slice in nested slice
    fmt.Println(nestedSlice[1][2]) // Output: 6
}

From Both:

package main

import (
    "fmt"
)

func main() {
    // Slices within a map
    mapOfSlices := map[string][]int{
        "numbers":      {1, 2, 3},
        "more_numbers": {4, 5, 6},
    }

    // Accessing the second value from the 'numbers' slice in mapOfSlices
    fmt.Println(mapOfSlices["numbers"][1]) // Output: 2
}
Common Operations on nested Structures

Modification of nested slices and maps resembles that of their non-nested versions in Go.

Operations on Nested Maps:

package main

import (
    "fmt"
)

func main() {
    // Map within a map
    nestedMap := map[string]map[string]string{
        "fruit": {
            "apple":  "red",
            "banana": "yellow",
        },
        "vegetable": {
            "carrot":  "orange",
            "spinach": "green",
        },
    }

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

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

    // Deleting apple from the 'fruit' map in nestedMap
    delete(nestedMap["fruit"], "apple")
}

Operations on Nested Slices:

package main

import (
    "fmt"
)

func main() {
    // Slices within a slice
    nestedSlice := [][]int{
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9},
    }

    // Adding 10 to the first slice in nestedSlice
    nestedSlice[0] = append(nestedSlice[0], 10)

    // Deleting the 2nd value from the 3rd slice in nestedSlice
    nestedSlice[2] = append(nestedSlice[2][:1], nestedSlice[2][2:]...)
}
Lesson Summary

Bravo! You've explored the world of nested slices and maps, structures that are becoming increasingly significant in data-driven applications. We've covered how to create, access, and modify values in these complex structures. Up next, we'll dive into hands-on practice sessions to solidify your understanding of these concepts. Get ready to apply what you've learned!

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