7. Slice of Slices

Slices can hold other slices, effectively creating a matrixarrow-up-right, or a 2D slice.

rows := [][]int{}
rows = append(rows, []int{1, 2, 3})
rows = append(rows, []int{4, 5, 6})
fmt.Println(rows)
// [[1 2 3] [4 5 6]]

Assignment

We support various visualization dashboards on Textio that display message analytics to our users. The UI for our graphs and charts is built on top of a grid system. Let's build some grid logic.

Complete the createMatrix function. It takes a number of rows and columns and returns a 2D slice of integers. The value of each cell is i * j where i and j are the indexes of the row and column respectively. Basically, we're building a multiplication chart.

For example, a 5x10 matrix, produced from calling createMatrix(5, 10), would look like this:

[0  0  0  0  0  0  0  0  0  0]
[0  1  2  3  4  5  6  7  8  9]
[0  2  4  6  8 10 12 14 16 18]
[0  3  6  9 12 15 18 21 24 27]
[0  4  8 12 16 20 24 28 32 36]

Solution

Concept

A slice of slices is Go's way of creating a 2D array or matrix. It's a slice where each element is itself another slice.

Visual Structure

Think of it like a table or spreadsheet:

Creating a 2D Slice

Basic Syntax

Building a Matrix with Loops

The key pattern is build from inside out:

1

Create the outer matrix container

Start with an empty outer slice that will hold rows.

2

Loop through rows

Iterate from 0 to rows-1. Each iteration handles one row.

3

For each row, create a new slice

Create an empty slice to hold the columns for the current row.

4

Loop through columns to fill that row

Iterate columns and append computed values to the current row.

5

Append the completed row to the matrix

After filling the row, append it to the outer matrix.

6

Return the matrix

Once all rows are processed, return the result.

Example: Multiplication Table

Output for createMatrix(3, 4):

Key Pattern: Two-Phase Append

This is the most important concept:

Common mistake:

Accessing Elements

Iterating Through a 2D Slice

Loop Types in Go

Standard For Loop (Counting)

Use when you need the index and know the range:

Range Loop

Use when iterating over a slice:

Important: You cannot use range with a number like range rows. Range only works with slices, arrays, maps, strings, or channels.

Mental Model: Packing Boxes

Think of building a 2D slice like packing boxes on shelves:

1

Get a box

Create an empty row:

2

Fill the box

Append items to the row:

3

Put box on shelf

Append the completed row to the matrix:

4

Repeat

Repeat for each row.

You must complete one box before putting it on the shelf. You can't put individual items directly on the shelf without a box!

Common Use Cases

  • Grids and game boards

  • Tables and spreadsheets

  • Matrices for mathematical operations

  • Pixel data for images

  • Graphs and charts data structures

Performance Note

If you know the size ahead of time, you can pre-allocate for better performance:

This avoids multiple append operations and slice reallocations.