Removing a string from a slice in Go

24,346

Solution 1

Find the element you want to remove and remove it like you would any element from any other slice.

Finding it is a linear search. Removing is one of the following slice tricks:

a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]

Here is the complete solution (try it on the Go Playground):

s := []string{"one", "two", "three"}

// Find and remove "two"
for i, v := range s {
    if v == "two" {
        s = append(s[:i], s[i+1:]...)
        break
    }
}

fmt.Println(s) // Prints [one three]

If you want to wrap it into a function:

func remove(s []string, r string) []string {
    for i, v := range s {
        if v == r {
            return append(s[:i], s[i+1:]...)
        }
    }
    return s
}

Using it:

s := []string{"one", "two", "three"}
s = remove(s, "two")
fmt.Println(s) // Prints [one three]

Solution 2

Here is a function to remove the element at a particular index:

package main

import "fmt"
import "errors"

func main() {
    strings := []string{}
    strings = append(strings, "one")
    strings = append(strings, "two")
    strings = append(strings, "three")
    strings, err := remove(strings, 1)
    if err != nil {
        fmt.Println("Something went wrong : ", err)
    } else {
        fmt.Println(strings)
    }

}

func remove(s []string, index int) ([]string, error) {
    if index >= len(s) {
        return nil, errors.New("Out of Range Error")
    }
    return append(s[:index], s[index+1:]...), nil
}

Try it on Go Playground

Share:
24,346
Patrick Reck
Author by

Patrick Reck

Updated on July 09, 2022

Comments

  • Patrick Reck
    Patrick Reck almost 2 years

    I have a slice of strings, and I want to remove a specific one.

    strings := []string
    strings = append(strings, "one")
    strings = append(strings, "two")
    strings = append(strings, "three")
    

    Now how can I remove the string "two" from strings?

  • Stanislav
    Stanislav over 5 years
    Fails in cases with multiple occurrence such as s := []string{"one", "two", "two", "three"}
  • icza
    icza over 5 years
    @Stanislav That's right, because intention was not to remove all occurrences, but to remove a string from a slice (as the question title says).
  • Benjamin R
    Benjamin R almost 4 years
    In defence of @Stanislav I get where he is coming from. I have no idea why append is a built-in but remove is not. Especially, when dealing with slices of strings, these are standard functions that practically every language in broad use other than C comes with out of the box. How many times has this sort of function had to be implemented when it could have been included in the standard library? We have a strings library for operating on string types as a slice of runes. This is part of the problem with an interface definition only being fulfilled on structs...
  • Muhammad Tariq
    Muhammad Tariq over 3 years
    Before removal, I have 2 elements [602139dfb72f0dec8cf66da6 602139dfb72f0dec8cf66da7] and after removal I get [ 602139dfb72f0dec8cf66da6]. You can see that I am getting a space. Do I need to trim this ? and how?
  • icza
    icza over 3 years
    @MuhammadTariq No, you do not. I don't see your code so I can't help you. It works for me.
  • Muhammad Tariq
    Muhammad Tariq over 3 years
    @icza, Here is the code for k, value := range mySlice{ if value == questionID { myslice = append(mySlice[:k], mySlice[k+1:]...) break } } When I print mySlice, I get the space as defined in above comment.
  • icza
    icza over 3 years
    You can't range over a slice and modify it at the same time. See How to remove element of struct array in loop in golang
  • Muhammad Tariq
    Muhammad Tariq over 3 years
    Thanks @icza. Actually the problem was my slice declaration var mySlice = make([]string,10). After some hit and try, I changed the capacity to ZERO var mySlice = make([]string,0) and it solved the problem. I checked with range and it gave me the correct result.
  • Lou
    Lou over 2 years
    Users may want to be aware that this will affect the original slice. If you run the 'remove' function and then try to access the original slice, it won't look the same. See play.golang.org/p/Sa2xYyk6atI