Deniz Tohumcu
Deniz Tohumcu

Reputation: 51

Why does my append function change every member of my slice to the new item to add?

I am making a simple prime factor function that can put a slice that is [][]int like

prime_factors_mult(315) => [[3,2],[5,1],[7,1]]

but instead of this result I get [[7,1][7,1][7,1][7,1]] which is afterwards reduced to a empty slice because they repeat them selfs. I tried to look at it with step by step and it changes all the values to the last append. What should I do to avoid this ?

func prime_factors_mult(x []int)(y [][]int){// Problem 36
    in :=[]int{0,0}
    var k [][]int
    for _,item := range x{
        tok := 0
        for i:=0;i<len(x);i++{
            if item == x[i]{
                tok++
            }
        }
        in[0]=item
        in[1]=tok
        k=append(k,in)
    }
    for _,item := range k{
        for i:=0;i<len(k);i++{
            if item[0] != k[i][0]{
                y = append(y,item)
            }
        }
    }
    return
}

Upvotes: 0

Views: 52

Answers (2)

Alon
Alon

Reputation: 107

Range's syntax returns the index and a reference of the value each time. You choose to use the reference both times, and the value gets modified but you keep on appending the same address. That's why you're only getting the last value, the range loop keeps modifying it and you're left with the last value from the loop.

approach 1:

To avoid this, change your loops to be for index := range k instead of for _,item := range k use the index from your loop and append k[index] instead of item.

approach 2:

for _, item range something {
  item := item

If you want to keep your syntax as is, you can create a local variable inside the loop, using the variable you got from range. Add item := item in the first line of both your loop blocks. though it looks weird, this will allocate new item every time, and you will append and use that variable instead.

Upvotes: 0

tkausl
tkausl

Reputation: 14269

You create your in slice once and then modify it each time, so you add the exact same object to k each time.

Append a new slice instead:

k=append(k,[]int{item, tok})

Upvotes: 2

Related Questions