'Moving an slice item from one position to another in 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?

go


Solution 1:[1]

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

Solution 2:[2]

Here's a simple shift right example without copy but also includes a loop showing how it's all really pointers.

Playground

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    for _, e := range s {
        // Will always shift 2 as it's been shifted each time
        fmt.Println(e, shiftRight(s, e))
    }
}

func shiftRight(s []int, e int) []int {
    if len(s) > 1 { // No where to shift to if 1 item
        // Go through the slice finding the item to shift
        for i, item := range s {
            if item == e {
                if i == len(s)-1 {
                    break // already at the end, can't shift any further
                }
                s[i] = s[i+1]
                s[i+1] = item
                break
            }
        }
    }
    return s
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 omotto
Solution 2 Tim