Skip to main content

Retrieving Collection Parts

Sometimes you do not need a whole slice. You need a part of it: a range of elements, the first or last few, pieces of equal size, or a moving window of neighbours.

Other languages have list methods like slice, take, drop, chunked and windowed. Go does not have these methods. Instead, Go has a slice expression: s[low:high] gives the elements from index low up to, but not including, index high. Leave out low to start at the beginning, or leave out high to go to the end.

A slice expression does not copy anything. The new slice shares memory with the original. If you change an element in the part, the original changes too. When you need an independent copy, use slices.Clone() from the slices package.

For the jobs that a slice expression cannot do on its own, this lesson uses a for loop, the slices package, or a small generic helper function.

Most examples on this page use the same data: the words one two three four five six.

Slice expression syntax

The three most common forms. n is a count or an index. The end index is never included.

main.go
s[low:high]   // elements from index low up to, but not including, high
s[:n]         // the first n elements
s[n:]         // everything from index n to the end

Slice

Slicing means taking the elements at some chosen positions.

For a run of neighbouring positions, use a slice expression: words[1:4] gives the elements at indexes 1, 2 and 3. Remember that the end index is excluded: to get the elements at indexes 1 to 3 you write 1:4.

A slice expression cannot skip elements. To take every second element, or elements at positions you list yourself, use a for loop and append() each picked element to a new slice.

Slice a range

words[1:4] starts at index 1 and stops before index 4. The result has 3 elements.

Prompt
Make a slice of the words one, two, three, four, five, six. Use a slice expression to take the elements from index 1 up to, but not including, index 4. Print the result.
Output: Go program and captured output
Slice a range

Slice with a step

To take every second element, a for loop with i += 2 visits indexes 0, 2 and 4 and collects the words.

Prompt
Make a slice of the words one, two, three, four, five, six. Use a for loop that goes from index 0 to index 4 in steps of 2 and appends each element to a new slice. Print the result.
Output: Go program and captured output
Slice with a step

Slice by a list of indices

The positions 3, 5 and 0 are stored in a slice of int. The loop picks the word at each position, so the result comes out in the order of the indices.

Prompt
Make a slice of the words one, two, three, four, five, six and a slice of indices 3, 5, 0. Loop over the indices and collect the words at those positions, in that order. Print the result.
Output: Go program and captured output
Slice by a list of indices

Take and Drop

Take means keep a number of elements from one end. Drop means throw away a number of elements from one end and keep the rest.

Both are slice expressions in Go. words[:3] takes the first 3 elements and words[len(words)-3:] takes the last 3. words[1:] drops the first element and words[:len(words)-5] drops the last 5.

There are also conditional versions: takeWhile, takeLastWhile, dropWhile and dropLastWhile. These do not count elements. They walk from one end and stop at the first element that fails a condition. Go has no built-in versions, so a small generic helper does the job: it finds the index where the condition stops holding and returns a slice expression from that index.

Take the first or last n elements

words[:3] keeps the first 3 words. words[len(words)-3:] keeps the last 3.

Prompt
Make a slice of the words one, two, three, four, five, six. Use slice expressions to get the first 3 elements and the last 3 elements. Print both results on separate lines.
Output: Go program and captured output
Take the first or last n elements

Drop the first or last n elements

words[1:] skips the first word. words[:len(words)-5] skips the last 5 words, so only one is left.

Prompt
Make a slice of the words one, two, three, four, five, six. Use slice expressions to get everything except the first element, and everything except the last 5 elements. Print both results on separate lines.
Output: Go program and captured output
Drop the first or last n elements

Take while a condition holds

TakeWhile keeps words from the start until it meets a word that starts with f. TakeLastWhile keeps words from the end until it meets three. strings.HasPrefix() checks the start of a string.

Prompt
Write generic TakeWhile and TakeLastWhile helpers that take a slice and a condition function. TakeWhile keeps elements from the start while the condition holds; TakeLastWhile does the same from the end. Use them on the words one, two, three, four, five, six: keep from the start while the word does not start with f, and keep from the end while the word is not three. Print both results.
Output: Go program and captured output
Take while a condition holds

Drop while a condition holds

DropWhile skips the 3-letter words at the start and keeps everything from three on. DropLastWhile skips words from the end while they contain the letter i. strings.Contains() checks whether a string holds a piece of text.

Prompt
Write generic DropWhile and DropLastWhile helpers that take a slice and a condition function. DropWhile skips elements from the start while the condition holds and keeps the rest; DropLastWhile does the same from the end. Use them on the words one, two, three, four, five, six: skip from the start while the word has 3 letters, and skip from the end while the word contains the letter i. Print both results.
Output: Go program and captured output
Drop while a condition holds

Chunked

Chunking means cutting a slice into pieces of the same size. The last piece may be shorter when the elements do not divide evenly.

Go has this built in since version 1.23: slices.Chunk(s, n). It does not return a slice of slices directly. It returns an iterator, which gives you the pieces one by one in a for range loop. Use slices.Collect() to gather all the pieces into a [][]int.

To work on each piece right away, loop over the chunks and do the work inside the loop.

Split into chunks of 3

The numbers 0 to 13 are cut into pieces of 3. The last piece has only 2 elements.

Prompt
Make a slice of the numbers 0 to 13. Use slices.Chunk to split it into pieces of 3 and slices.Collect to gather the pieces into a slice of slices. Print the result.
Output: Go program and captured output
Split into chunks of 3

Sum each chunk

The same chunks, but each one is added up inside the loop. Only the sums are kept.

Prompt
Make a slice of the numbers 0 to 13. Loop over slices.Chunk with a chunk size of 3, add up the numbers in each chunk and append the sum to a new slice. Print the slice of sums.
Output: Go program and captured output
Sum each chunk

Windowed

A window is a group of neighbouring elements. Windowing slides the group along the slice and collects every position. Unlike chunks, windows overlap.

Go has no built-in windowed. A for loop with a slice expression items[i:i+size] does it. A small generic Windowed helper makes it reusable. With a step, the window moves several positions at a time. With partial set to true, a shorter window at the end is kept instead of being thrown away.

A window of 2 that moves 1 step is the same as pairing each element with the next one. In Go it is a loop that stops one element before the end.

Windows of 3

The window has 3 words and moves 1 position each time. The loop stops when a full window no longer fits.

Prompt
Write a generic Windowed helper that takes a slice and a window size and returns every group of that many neighbouring elements, moving one position at a time. Use it with size 3 on the words one, two, three, four, five. Print the result.
Output: Go program and captured output
Windows of 3

Windows with a step and partial windows

The window has 3 numbers and moves 2 positions each time. Because partial is true, the last window [9 10] is kept even though it is short.

Prompt
Write a generic Windowed helper that takes a slice, a window size, a step and a partial flag. It moves step positions between windows, and when partial is true it also keeps a shorter window at the end. Use it on the numbers 1 to 10 with size 3, step 2 and partial set to true. Print the result.
Output: Go program and captured output
Windows with a step and partial windows

Sum each window

Every window of 3 neighbours is added up. Only the sums are kept.

Prompt
Make a slice of the numbers 1 to 5. Loop over every window of 3 neighbouring elements, add up the numbers in the window and append the sum to a new slice. Print the slice of sums.
Output: Go program and captured output
Sum each window

Pair each element with the next one

The first loop builds a Pair from each word and its neighbour. The second loop compares the same neighbours and records whether the first word is longer than the second.

Prompt
Make a slice of the words one, two, three, four, five. Loop over the slice and pair each element with the one after it, using a small Pair struct, and print the slice of pairs. Then loop again and, for each pair of neighbours, record whether the first word is longer than the second. Print the slice of booleans.
Output: Go program and captured output
Pair each element with the next one