Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving an slice item from one position to another in go

Tags:

go

I' trying to move an item from one position to another inside a slice. Go Playground

indexToRemove := 1
indexWhereToInsert := 4

slice := []int{0,1,2,3,4,5,6,7,8,9}    

slice = append(slice[:indexToRemove], slice[indexToRemove+1:]...)
fmt.Println("slice:", slice)    

newSlice := append(slice[:indexWhereToInsert], 1)
fmt.Println("newSlice:", newSlice)

slice = append(newSlice, slice[indexWhereToInsert:]...)
fmt.Println("slice:", slice)

This produces to following output:

slice: [0 2 3 4 5 6 7 8 9]
newSlice: [0 2 3 4 1]
slice: [0 2 3 4 1 1 6 7 8 9] 

But I would expect the output be like this:

slice: [0 2 3 4 5 6 7 8 9]
newSlice: [0 2 3 4 1]
slice: [0 2 3 4 1 **5** 6 7 8 9] 

Where is my fault?

like image 379
David Avatar asked Apr 25 '17 16:04

David


People also ask

How do I remove an item from a slice in go?

Removing an Element from a Slice Items need to be removed from a slice by slicing them out. To remove an element, you must slice out the items before that element, slice out the items after that element, then append these two new slices together without the element that you wanted to remove.

What is difference between array and slice in Golang?

Slices in Go and Golang The basic difference between a slice and an array is that a slice is a reference to a contiguous segment of an array. Unlike an array, which is a value-type, slice is a reference type. A slice can be a complete array or a part of an array, indicated by the start and end index.

How do I add a slice in Golang?

To add an element to a slice , you can use Golang's built-in append method. append adds elements from the end of the slice. The first parameter to the append method is a slice of type T . Any additional parameters are taken as the values to add to the given slice .

What is slice Golang?

Slice is a variable-length sequence which stores elements of a similar type, you are not allowed to store different type of elements in the same slice. It is just like an array having an index value and length, but the size of the slice is resized they are not in fixed-size just like an array.


2 Answers

I had the same issue before and I solved as:

func insertInt(array []int, value int, index int) []int {
    return append(array[:index], append([]int{value}, array[index:]...)...)
}

func removeInt(array []int, index int) []int {
    return append(array[:index], array[index+1:]...)
}

func moveInt(array []int, srcIndex int, dstIndex int) []int {
    value := array[srcIndex]
    return insertInt(removeInt(array, srcIndex), value, dstIndex)
}


func main() {
    slice := []int{0,1,2,3,4,5,6,7,8,9}

    fmt.Println("slice: ", slice)

    slice = insertInt(slice, 2, 5)  
    fmt.Println("slice: ", slice)

    slice = removeInt(slice, 5) 
    fmt.Println("slice: ", slice)

    slice = moveInt(slice, 1, 4) 
    fmt.Println("slice: ", slice)
}

https://play.golang.org/p/Sfu1VsySieS

like image 77
omotto Avatar answered Sep 20 '22 00:09

omotto


The problem is that newSlice is not a distinct copy of slice--they reference the same underlying array.

So when you assign to newSlice, you're modifying the underlying array, and thus slice, too.

To remedy this, you need to make an explicit copy:

Playground

package main

import (
    "fmt"
)

func main() {

    indexToRemove := 1
    indexWhereToInsert := 4

    slice := []int{0,1,2,3,4,5,6,7,8,9}

    val := slice[indexToRemove]

    slice = append(slice[:indexToRemove], slice[indexToRemove+1:]...)
    fmt.Println("slice:", slice)    

    newSlice := make([]int, indexWhereToInsert+1)
    copy(newSlice,slice[:indexWhereToInsert])
    newSlice[indexWhereToInsert]=val
    fmt.Println("newSlice:", newSlice)
    fmt.Println("slice:", slice)

    slice = append(newSlice, slice[indexWhereToInsert:]...)
    fmt.Println("slice:", slice)    
}

(Note that I've also added the val variable, rather than hardcoding 1 as the value to be inserted.)

like image 28
Flimzy Avatar answered Sep 22 '22 00:09

Flimzy