Remove or Delete Elements from a Slice in Go (First, Last, by Index)

Remove the first or last element from a slice in Go, delete by index while keeping order or in O(1) with swap-and-truncate, drop a run of elements, and use slices.Delete on Go 1.21+.

Published

Updated

Read time 4 min read

Reviewed byDeepak Prasad

Remove or Delete Elements from a Slice in Go (First, Last, by Index)

Slices in Go are descriptors over a backing array: length, capacity, and a pointer. Golang slice delete and golang remove from slice almost always mean changing the length (and sometimes capacity) by reslicing or by copy and append patterns. Searchers ask for golang remove last element from slice, golang slice remove last element, go remove last element from slice, remove last element from slice golang, golang remove first element from slice, golang remove element from slice, golang remove item from slice, and golang delete from slice; those map to a small set of idioms plus slices.Delete on modern Go.

Tested with Go 1.24 on Linux.


Drop the first or last element (prefix and suffix)

Golang remove first element from slice: use s = s[1:] when len(s) > 0. To drop the first n elements, use s = s[n:] after validating 0 <= n <= len(s).

Golang remove last element from slice and golang slice remove last element: use s = s[:len(s)-1] when len(s) > 0. To drop the last n elements, s = s[:len(s)-n] with the same bound check.

Run the program: you should see [2 3 4 5], then [2 3 4], then [4] after dropping one from the front, one from the end, then two from the front.

go
package main

import "fmt"

func main() {
	s := []int{1, 2, 3, 4, 5}
	if len(s) > 0 {
		s = s[1:]
	}
	fmt.Println(s)

	if len(s) > 0 {
		s = s[:len(s)-1]
	}
	fmt.Println(s)

	n := 2
	if n <= len(s) {
		s = s[n:]
	}
	fmt.Println(s)
}
Output

If n can be out of range, clamp or return early instead of reslicing (bad indices panic).


Remove one element by index

Keep order (typical golang remove element from slice)

Shift everything after the index forward with copy, then shorten:

go
package main

import "fmt"

func removeOrdered(s []int, i int) []int {
	if i < 0 || i >= len(s) {
		return s
	}
	copy(s[i:], s[i+1:])
	return s[:len(s)-1]
}

func main() {
	s := []int{1, 2, 3, 4, 5}
	s = removeOrdered(s, 2)
	fmt.Println(s)
}
Output

You should see [1 2 4 5]. Time cost is O(len(s) - i) because of copy.

Do not keep order (O(1) delete at index)

Swap the victim with the last element, then truncate:

go
package main

import "fmt"

func removeSwap(s []int, i int) []int {
	if i < 0 || i >= len(s) {
		return s
	}
	s[i] = s[len(s)-1]
	return s[:len(s)-1]
}

func main() {
	s := []int{1, 2, 3, 4, 5}
	s = removeSwap(s, 1)
	fmt.Println(s)
}
Output

Output order among the survivors is not the original order; this is O(1).


Go 1.21+: slices.Delete for golang delete from slice

The slices package provides slices.Delete, which removes s[i:j] and returns the new slice header (same idea as append(s[:i], s[j:]...)).

go
package main

import (
	"fmt"
	"slices"
)

func main() {
	s := []int{1, 2, 3, 4, 5}
	s = slices.Delete(s, 2, 3)
	fmt.Println(s)

	s = slices.Delete(s, 0, 2)
	fmt.Println(s)
}
Output

You should see [1 2 4 5] then [4 5]. Requires Go 1.21 or newer.


Remove several elements starting at an index

With copy, move the block after index+n down to index, then shorten by n:

go
package main

import "fmt"

func removeRange(s []int, index, n int) []int {
	if n <= 0 || index < 0 || index > len(s) || index+n > len(s) {
		return s
	}
	copy(s[index:], s[index+n:])
	return s[:len(s)-n]
}

func main() {
	s := []int{1, 2, 3, 4, 5}
	s = removeRange(s, 1, 2)
	fmt.Println(s)
}
Output

You should see [1 4 5]. On Go 1.21+, slices.Delete(s, index, index+n) is equivalent and often clearer.


Random index (example only)

To golang remove item from slice at a pseudorandom index for demos, use math/rand and rand.Intn(len(s)) after checking len(s) > 0. Never call rand.Intn(0)—that panics.


Summary

Golang remove last element from slice and golang remove first element from slice use s[:len(s)-1] and s[1:] with length checks. Golang remove element from slice at index i while keeping order uses copy(s[i:], s[i+1:]) and s[:len(s)-1], or slices.Delete(s, i, i+1) on Go 1.21+. Golang delete from slice for a span is copy plus truncate or slices.Delete(s, i, j). Swap-and-truncate is O(1) at the cost of order. Clearer copy can help when you already get impressions, but traffic is not guaranteed to jump from one refresh alone.


References


Frequently Asked Questions

1. How do I golang remove last element from a slice?

Reslice with s = s[:len(s)-1] after checking len(s) > 0. On Go 1.21 or newer you can also write s = s[:max(0, len(s)-1)] or use slices.Delete(s, len(s)-1, len(s)) for symmetry with other removals.

2. How do I golang remove first element from a slice?

Drop the prefix with s = s[1:] when len(s) > 0, or s = s[n:] to remove the first n elements. This reuses the same backing array; the zero slot is still reachable until the slice is garbage-collected if nothing else references it.

3. How do I golang remove element from slice at an index and keep order?

Shift the tail with copy(s[i:], s[i+1:]) then shorten with s = s[:len(s)-1], or use slices.Delete(s, i, i+1) on Go 1.21+. Cost is O(n - i) because elements after i move.

4. How do I delete from a slice in O(1) time without preserving order?

Move the last element into the slot you want to remove, then truncate one element from the end: s[i] = s[len(s)-1]; s = s[:len(s)-1]. This does not preserve relative order among the remaining elements.

5. When should I use slices.Delete instead of append?

slices.Delete(s, i, j) is the standard library helper that removes s[i:j] and returns the shortened slice; it is equivalent to append(s[:i], s[j:]...) but clearer and available from Go 1.21 onward in the slices package.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …