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.
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:
Go1package 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 structures in Go is straightforward, thanks to the language's versatile nature.
Nested Map:
Go1package 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:
Go1package 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:
Go1package 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 from nested maps or slices in Go follows similar principles as their non-nested counterparts.
From Nested Map:
Go1package 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:
Go1package 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:
Go1package 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}
Modification of nested slices and maps resembles that of their non-nested versions in Go.
Operations on Nested Maps:
Go1package 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:
Go1package 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}
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!