YouTip LogoYouTip

Go Multi Dimensional Arrays

[![Image 1: Go Language Arrays](#)Go Language Arrays](#) Multi-dimensional arrays are arrays of arrays. You can think of them as a **data table** or **matrix**, where each element can be accessed via multiple indices. In Go, multi-dimensional arrays can be used to handle structured information such as tabular data, matrix operations, or game boards. ### Basic Concepts * **One-dimensional array**: Like points on a straight line, you only need one coordinate (index) to find a specific element. * **Two-dimensional array**: Like a table, you need two coordinates: row and column. * **Three-dimensional array**: Like a cube, you need three coordinates: length, width, and height. * **Higher dimensions**: Theoretically, there can be many dimensions, but in practice, two and three dimensions are most commonly used. We can draw an analogy from our daily parking spaces: * **One-dimensional array** = A row of parking spaces (only need the space number). * **Two-dimensional array** = A multi-story parking garage (need floor and space number). * **Three-dimensional array** = Multiple multi-story parking garages (need garage number, floor, and space number). Go supports multi-dimensional arrays. The following are common ways to declare multi-dimensional arrays: var variable_name ... variable_type Declaration and Initialization: // Declare a two-dimensional array var arrayName elementType // Declare and initialize var arrayName elementType = elementType{initialization values} The following example declares a three-dimensional integer array: var threedim int * * * ## Two-dimensional Arrays A two-dimensional array is the simplest multi-dimensional array. A two-dimensional array is essentially composed of one-dimensional arrays. The definition of a two-dimensional array is as follows: var arrayName variable_type `variable_type` is the data type in Go, `arrayName` is the array name. A two-dimensional array can be considered a table, where `x` is the row and `y` is the column. The following diagram illustrates a two-dimensional array `a` with three rows and four columns: !(#) Elements in a two-dimensional array can be accessed via `a`. ## Example package main import "fmt" func main() { // Step 1: Create an array values := [][]int{} // Step 2: Use the append() function to add two one-dimensional arrays (rows) to the empty two-dimensional array row1 := []int{1, 2, 3} row2 := []int{4, 5, 6} values = append(values, row1) values = append(values, row2) // Step 3: Display the two rows of data fmt.Println("Row 1") fmt.Println(values) fmt.Println("Row 2") fmt.Println(values) // Step 4: Access the first element fmt.Println("The first element is:") fmt.Println(values) } The output of the above example is: Row 1 Row 2 The first element is: 1 * * * ## Initializing Two-dimensional Arrays Multi-dimensional arrays can be initialized using curly braces. The following example is a two-dimensional array with 3 rows and 4 columns: a := int{ {0, 1, 2, 3}, /* Row index 0 */ {4, 5, 6, 7}, /* Row index 1 */ {8, 9, 10, 11}, /* Row index 2 */ } > **Note:** In the code above, the second-to-last line's **}** must have a comma, because the last line's **}** cannot be on a line by itself. It can also be written as: a := int{ {0, 1, 2, 3}, /* Row index 0 */ {4, 5, 6, 7}, /* Row index 1 */ {8, 9, 10, 11}} /* Row index 2 */ The following example initializes a two-dimensional array with 2 rows and 2 columns: ## Example package main import "fmt" func main() { // Create a two-dimensional array sites := string{} // Add elements to the two-dimensional array sites = "Google" sites = "" sites = "Taobao" sites = "Weibo" // Display the result fmt.Println(sites) } The output of the above example is: [ ] * * * ## Accessing Two-dimensional Arrays A two-dimensional array is accessed by specifying coordinates, such as the row index and column index in the array. For example: val := a or var value int = a The above example accesses the fourth element of the third row in the two-dimensional array `val`. Two-dimensional arrays can use nested loops to output elements: ## Example package main import "fmt" func main() { /* Array - 5 rows, 2 columns */ var a = int{{0, 0}, {1, 2}, {2, 4}, {3, 6}, {4, 8}} var i, j int /* Output array elements */ for i = 0; i < 5; i++ { for j = 0; j < 2; j++ { fmt.Printf("a[%d][%d] = %dn", i, j, a) } } } The output of the above example is: a = 0 a = 0 a = 1 a = 2 a = 2 a = 4 a = 3 a = 6 a = 4 a = 8 The following example creates a multi-dimensional array where the number of elements in each dimension is not consistent: ## Example package main import "fmt" func main() { // Create an empty two-dimensional array animals := [][]string{} // Create three one-dimensional arrays, each of different length row1 := []string{"fish", "shark", "eel"} row2 := []string{"bird"} row3 := []string{"lizard", "salamander"} // Use the append() function to add the one-dimensional arrays to the two-dimensional array animals = append(animals, row1) animals = append(animals, row2) animals = append(animals, row3) // Loop and output for i := range animals { fmt.Printf("Row: %vn", i) fmt.Println(animals) } } The output of the above example is: Row: 0 Row: 1 Row: 2 * * * ## Accessing and Modifying Array Elements ### Accessing Elements ## Example package main import "fmt" func main() { // Create a 3x3 matrix matrix := int{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, } // Access a single element fmt.Println("Row 1, Column 2:", matrix) // Output: 2 fmt.Println("Row 3, Column 3:", matrix) // Output: 9 // Access an entire row fmt.Println("Row 2:", matrix) // Output: // Traverse all elements fmt.Println("nTraversing all elements:") for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { fmt.Printf("matrix[%d][%d] = %dn", i, j, matrix) } } } ### Modifying Elements ## Example package main import "fmt" func main() { // Create a 2x2 zero-value matrix var grid int fmt.Println("Matrix before modification:", grid) // Modify elements at specific positions grid = 10 grid = 20 grid = 30 grid = 40 fmt.Println("Matrix after modification:", grid) // Batch modify a row grid = int{100, 200} fmt.Println("After modifying the first row:", grid) } * * * ## Three-dimensional and Higher-dimensional Arrays ### Three-dimensional Array Example ## Example package main import "fmt" func main() { // Declare a 2x3x4 three-dimensional array // Can be understood as: 2 planes, each plane has 3 rows and 4 columns var cube int // Initialize the three-dimensional array cube = int{ { // First plane {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, }, { // Second plane {13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}, }, } // Access three-dimensional array elements fmt.Println("cube =", cube) // Output: 7 fmt.Println("cube =", cube) // Output: 24 // Traverse the three-dimensional array fmt.Println("nThree-dimensional array content:") for i := 0; i < 2; i++ { fmt.Printf("Plane %d:n", i) for j := 0; j < 3; j++ { for k := 0; k < 4; k++ { fmt.Printf("%3d ", cube) } fmt.Println() } fmt.Println() } } **See the diagram below:** !(#) * * * ## Common Operations on Multi-dimensional Arrays ### 1. Traversal using `range` ## Example package main import "fmt" func main() { // Create a two-dimensional array scores := int{ {85, 90, 78, 92}, {88, 76, 95, 89}, {92, 85, 88, 90}, } fmt.Println("Student Grade Table:") // Use range to traverse the two-dimensional array for i, row := range scores { fmt.Printf("Student %d's grades: ", i+1) for j, score := range row { fmt.Printf("%d ", score) // If you need both index and value _ = j // Avoid unused variable warning } fmt.Println() } // Only care about values, not indices total := 0 count := 0 for _, row := range scores { for _, score := range row { total += score count++ } } fmt.Printf("nAverage score: %.2fn", float64(total)/float64(count)) } ### 2. Getting Array Length ## Example package main import "fmt" func main() { // Create an irregular multi-dimensional array (Note: This is invalid in Go, as shown in the comment) // jagged := int{ // {1, 2, 3}, // {4, 5}, // This row has only 2 elements // {6, 7, 8, 9}, // This row has 4 elements. Note: This will cause a compile error because each row must have the same length. // } // Correct example: Get array dimensions matrix := int{} // Get the number of rows rows := len(matrix) fmt.Println("Rows:", rows) // Output: 4 // Get the number of columns in the first row (all rows have the same length) cols := len(matrix) fmt.Println("Columns:", cols) // Output: 5 // Get the total number of elements totalElements := rows * cols fmt.Println("Total elements:", totalElements) // Output: 20 } ### 3. Array Comparison ## Example package main import "fmt" func main() { // Create two identical two-dimensional arrays a := int{{1, 2}, {3, 4}} b := int{{1, 2}, {3, 4}} c := int{{1, 2}, {3, 5}} // Arrays can be compared directly (only when dimensions are exactly the same) fmt.Println("a == b:", a == b) // Output: true fmt.Println("a == c:", a == c) // Output: false // Note: Arrays of different dimensions cannot be compared // d := int{{1, 2, 3}, {4, 5, 6}} // fmt.Println(a == d) // Compile error: type mismatch } * * * ## Practical Application Scenarios ### Scenario 1: Game Board (Tic-Tac-Toe) ## Example package main import "fmt" func main() { // Initialize a 3x3 Tic-Tac-Toe board var board string // Initialize to empty for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { board = " " } } // Simulate moves board = "X" board = "O" board = "X" // Print the board fmt.Println("Tic-Tac-Toe Board:") for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { fmt.Printf(" %s ", board) if j < 2 { fmt.Printf("|") } } fmt.Println() if i < 2 { fmt.Println("---+---+---") } } } ### Scenario 2: Student Grade Management System ## Example package main import "fmt" func main() { // Define: 3 students, each with 4 courses var grades float64 // Input student grades grades = float64{ {85.5, 90.0, 78.5, 92.0}, // Student 1's grades {88.0, 76.5, 95.0, 89.5}, // Student 2's grades {92.5, 85.0, 88.5, 90.0}, // Student 3's grades } // Calculate the average grade for each student fmt.Println("Student Grade Statistics:") for i, studentGrades := range grades { sum := 0.0 for _, grade := range studentGrades { sum += grade } average := sum / float64(len(studentGrades)) fmt.Printf("Student %d: Average = %.2fn", i+1, average) } // Calculate the average grade for each course fmt.Println("nCourse Averages:") for j := 0; j < 4; j++ { sum := 0.0 for i := 0; i < 3; i++ { sum += grades } average := sum / 3.0 fmt.Printf("Course %d: Average = %.2fn", j+1, average) } } ### Scenario 3: Image Pixel Processing ## Example package main import "fmt" func main() { // Simulate a simple 3x3 grayscale image // Each pixel value range: 0 (black) ~ 255 (white) var image int // Initialize the image (a simple gradient) for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { image = (i + j) * 50 } } // Display the original image fmt.Println("Original Image:") displayImage(image) // Image processing: Increase brightness fmt.Println("nImage after increasing brightness:") for i := 0; i < 3; i++ { for j := 0; j 255 { newValue = 255 } image = newValue } } displayImage(image) } func displayImage(img int) { for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { fmt.Printf("%3d ", img) } fmt.Println() } } * * * ## Notes and Best Practices ### 1. Array Length is Part of the Type ## Example package main import "fmt" func main() { // These two are different types! var a int var b int // The following code will cause a compile error // a = b // Error: type mismatch fmt.Printf("Type of a: %Tn", a) // int fmt.Printf("Type of b: %Tn", b) // int } ### 2. Value Type vs Reference Type ## Example package main import "fmt" func main() { // Arrays are value types original := int{{1, 2}, {3, 4}} // Assignment creates a copy copy := original // Modifying the copy does not affect the original array copy = 100 fmt.Println("Original array:", original) // [ ] fmt.Println("Copy array:", copy) // [ ] // If you need reference semantics, you can use slices (covered in a later article) } ### 3. Performance Considerations * **Contiguous Memory**: Multi-dimensional arrays are stored contiguously in memory, leading to fast access. * **Fixed Size**: The array length is determined at compile time and cannot be changed dynamically. * **Suitable Scenarios**: When the data size is known and fixed, arrays are the best choice. * * * ## Frequently Asked Questions ### Q1: What is the difference between multi-dimensional arrays and nested slices? | Feature | Multi-dimensional Arrays | Nested Slices | | --- | --- | --- | | Size | Fixed, determined at compile time | Dynamic, variable at runtime | | Memory | Contiguous allocation | May not be contiguous | | Performance | Fast access | Slightly slower, with overhead | | Use Case | Data size is known | Data size is variable | ### Q2: How to create an irregular two-dimensional array? Go arrays require each row to have the same length. If you need an irregular structure, you should use slices: ## Example // Use slices to create an irregular structure irregular := [][]int{ {1, 2, 3}, {4, 5}, // This row has only 2 elements {6, 7, 8, 9}, // This row has 4 elements } ### Q3: Can multi-dimensional arrays be used as function parameters? Yes, but be aware that arrays are value types, and passing large arrays can have performance overhead: ## Example func processMatrix(matrix int) int { // Process the matrix... matrix = 100 return matrix } // A better way is to use pointers or slices func processMatrixPtr(matrix *int) { matrix = 100 } [![Image 4: Go Language Arrays](#)Go Language Arrays](#)
← Go ArraysGo Method β†’