How to delete an element from a slice in Go

Created
Modified

Faster Version

If you do not care about ordering, you have the much faster possibility to replace the element to delete with the one at the end of the slice and then return the n-1 first elements:

package main

import "fmt"

func Remove(s []string, i int) []string {
  if len(s) == 0 {
    return s
  }
  if i == 0 {
    return s[1:]
  }
  if i == len(s)-1 {
    return s[:len(s)-1]
  }
  s[i] = s[len(s)-1]
  return s[:len(s)-1]
}

func main() {
  s := []string{"a", "b", "c", "d", "e", "f"}

  a := Remove(s, 2)
  fmt.Printf("%q\n", a)

  s = []string{"a", "b", "c", "d", "e", "f"}
  a = Remove(s, 0)
  fmt.Printf("%q\n", a)

  s = []string{"a", "b", "c", "d", "e", "f"}
  a = Remove(s, 5)
  fmt.Printf("%q\n", a)
}
["a" "b" "f" "d" "e"]
["b" "c" "d" "e" "f"]
["a" "b" "c" "d" "e"]

if i >= len(s), will cause Go to panic. panic: runtime error: index out of range [20] with length 6.

Using append Function

If you want to keep your array ordered, you have to shift all of the elements at the right of the deleting index by one to the left. Hopefully, this can be done easily in Golang:

package main

import "fmt"

func Remove(s []string, i int) []string {

  return append(s[:i], s[i+1:]...)
}

func main() {
  s := []string{"a", "b", "c", "d", "e", "f"}

  a := Remove(s, 2)
  fmt.Printf("%q\n", a)
}
["a" "b" "d" "e" "f"]

However, this is inefficient because you may end up with moving all of the elements, which is costly.

Using copy Function

For example,

package main

import "fmt"

func Remove(s []string, i int) []string {
  copy(s[i:], s[i+1:])
  return s[:len(s)-1]
}

func main() {
  s := []string{"a", "b", "c", "d", "e", "f"}

  a := Remove(s, 2)
  fmt.Printf("%q\n", a)
}
["a" "b" "d" "e" "f"]

The code copies len(a) - i - 1 elements and runs in linear time.

Related Tags