How to remove an item from a slice repeatedly?

Issue

I would like to create multiple slices from one array. One slice each with one element missing. I am using this code (playground):

nums := []int{1,2,3}
for i := 0; i < len(nums); i++ {
    fmt.Println(append(nums[:i], nums[i+1:]...))
}

I was expecting to receive

[2 3]
[1 3]
[1 2]

But instead I receive

[2 3]
[2 3]
[2 3]

Why is that?

Solution

As mkopriva correctly pointed out, the output of your program differs from what you expect because all slices resulting from append share the same underlying array. You need to somehow decouple those slices from the underlying array of slice nums.

One viable approach is indeed to use copy, as you did in your answer. There is a more concise alternative, although it may not be clearer to untrained eyes.

Rather than resorting to copy, you can use nums[:i:i] (a full-slice expression, a.k.a. three-index slice) as the first argument of append:

nums := []int{1,2,3}
for i := 0; i < len(nums); i++ {
  fmt.Println(append(nums[:i:i], nums[i+1:]...))
}

The resulting slice will be decoupled from slice nums‘s underlying array and you’ll get the desired output:

[2 3]
[1 3]
[1 2]

(Playground)

Since Go 1.18, you can use functions Clone and Delete from the golang.org/x/exp/slices package to achieve the same result with arguably more readable code:

func main() {
  nums := []int{1, 2, 3}
  for i := 0; i < len(nums); i++ {
    fmt.Println(slices.Delete(slices.Clone(nums), i, i+1))
  }
}

(Playground)

Answered By – jub0bs

Answer Checked By – Mary Flores (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.