Lesson 4
Compound Data Structures in Go
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:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Map with grades (int) as keys and slices of students (strings) as values 9 schoolDirectory := map[int][]string{ 10 1: {"Amy", "Bobby", "Charlie"}, 11 2: {"David", "Eve", "Frank"}, 12 3: {"George", "Hannah", "Ivy"}, 13 } 14 15 // Prints the Grade1 list in the map 16 for _, student := range schoolDirectory[1] { 17 fmt.Print(student, " ") 18 } 19 // Output: Amy Bobby Charlie 20}
Creating Nested Maps and Slices

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

Nested Map:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Map within a map 9 nestedMap := map[string]map[string]string{ 10 "fruit": { 11 "apple": "red", 12 "banana": "yellow", 13 }, 14 "vegetable": { 15 "carrot": "orange", 16 "spinach": "green", 17 }, 18 } 19 20 // Prints the nested map 21 for category, items := range nestedMap { 22 fmt.Print(category, ": ") 23 for item, color := range items { 24 fmt.Print(item, "(", color, ") ") 25 } 26 fmt.Println() 27 } 28}

Nested Slice:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Slices within a slice 9 nestedSlice := [][]int{ 10 {1, 2, 3}, 11 {4, 5, 6}, 12 {7, 8, 9}, 13 } 14 15 // Prints the nested slice 16 for _, slice := range nestedSlice { 17 for _, val := range slice { 18 fmt.Print(val, " ") 19 } 20 fmt.Println() 21 } 22}

Nested Maps and Slices:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Slices within a map 9 mapOfSlices := map[string][]int{ 10 "numbers": {1, 2, 3}, 11 "more_numbers": {4, 5, 6}, 12 } 13 14 // Prints the map of slices 15 for key, slice := range mapOfSlices { 16 fmt.Print(key, ": ") 17 for _, val := range slice { 18 fmt.Print(val, " ") 19 } 20 fmt.Println() 21 } 22}
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:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Map within a map 9 nestedMap := map[string]map[string]string{ 10 "fruit": { 11 "apple": "red", 12 "banana": "yellow", 13 }, 14 "vegetable": { 15 "carrot": "orange", 16 "spinach": "green", 17 }, 18 } 19 20 // Accessing apple's color from nested map 21 fmt.Println(nestedMap["fruit"]["apple"]) // Output: red 22}

From Nested Slice:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Slices within a slice 9 nestedSlice := [][]int{ 10 {1, 2, 3}, 11 {4, 5, 6}, 12 {7, 8, 9}, 13 } 14 15 // Accessing the 3rd value from the 2nd slice in nested slice 16 fmt.Println(nestedSlice[1][2]) // Output: 6 17}

From Both:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Slices within a map 9 mapOfSlices := map[string][]int{ 10 "numbers": {1, 2, 3}, 11 "more_numbers": {4, 5, 6}, 12 } 13 14 // Accessing the second value from the 'numbers' slice in mapOfSlices 15 fmt.Println(mapOfSlices["numbers"][1]) // Output: 2 16}
Common Operations on nested Structures

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

Operations on Nested Maps:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Map within a map 9 nestedMap := map[string]map[string]string{ 10 "fruit": { 11 "apple": "red", 12 "banana": "yellow", 13 }, 14 "vegetable": { 15 "carrot": "orange", 16 "spinach": "green", 17 }, 18 } 19 20 // Modifying spinach's color to red 21 nestedMap["vegetable"]["spinach"] = "red" 22 23 // Adding cherry to the 'fruit' map in nestedMap 24 nestedMap["fruit"]["cherry"] = "red" 25 26 // Deleting apple from the 'fruit' map in nestedMap 27 delete(nestedMap["fruit"], "apple") 28}

Operations on Nested Slices:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func main() { 8 // Slices within a slice 9 nestedSlice := [][]int{ 10 {1, 2, 3}, 11 {4, 5, 6}, 12 {7, 8, 9}, 13 } 14 15 // Adding 10 to the first slice in nestedSlice 16 nestedSlice[0] = append(nestedSlice[0], 10) 17 18 // Deleting the 2nd value from the 3rd slice in nestedSlice 19 nestedSlice[2] = append(nestedSlice[2][:1], nestedSlice[2][2:]...) 20}
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!

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