-5

I am writing a program to generate all possible permutations of a slice of unique elements. The code for the same can be found here

At one point I need to create a new slice from the original slice of numbers. This new slice has one less element than the original slice. I tried two different variants with append

nums is the original slice and remaining is the new slice I am trying to create. i is an int which can range from 0 to len(nums)-1.

Variant 1:

remaining := make([]int, 0)
remaining = append(remaining, nums[:i]...)
remaining = append(remaining, nums[i+1:]...)

Variant 2:

remaining := append(nums[:i], nums[i+1:]...)

While the program works fine with Variant 1 , it doesn't behave correctly with Variant 2. I want to understand what is the exact difference in these two Variants ?

Abhishek Jha
  • 935
  • 2
  • 10
  • 22
  • 1
    You are using slice having same array backing, means `nums` also modified see [here](https://play.golang.org/p/cAwYaFJDxuC) – Eklavya Aug 20 '20 at 08:15
  • I recommend you explore [slices-intro](https://blog.golang.org/slices-intro) – Eklavya Aug 20 '20 at 08:21
  • neither `nums` nor `remaining` is ever mutated? What exactly is causing the modification? – Abhishek Jha Aug 20 '20 at 08:24
  • 2
    See this answer: [Concatenate two slices in Go](https://stackoverflow.com/questions/16248241/concatenate-two-slices-in-go/40036950?r=SearchResults#40036950). – icza Aug 20 '20 at 08:34
  • 1
    You are appending in nums so "1 2 3" became "2 3 3" – Eklavya Aug 20 '20 at 08:34
  • 3
    Do not use `append` to create a new slice, use it to append to a slice. To create a new slice, use a slice literal or `make()`. To copy data from an existing slice to the new slice, use `copy()`. – Adrian Aug 20 '20 at 13:37

1 Answers1

0

Here slice nums[:i] is created by slicing a bigger array nums. This leads to it having enough capacity to extend in place. So an operation like append(nums[:i], nums[i+1:]...) causes the elements in nums getting overridden by elements from nums[i+1:]. This mutates the original array and hence the behaviour.

As suggested by @icza the concept has been capture here.

To fix the Variant 2 we can use full slice expression like this

remaining := append(nums[0:i:i], nums[i+1:len(nums):len(nums)]...)
Abhishek Jha
  • 935
  • 2
  • 10
  • 22