In place deletion of Golang slice elements

go, in-place, slice

Solution

I'd do it by moving elements, then resizing the slice, and using a pointer. Something like this:

package main

import "fmt"

type Ints []int

func (xs *Ints) Filter() {
    filterPos := 0
    for i := 0; i < len(*xs); i++ {
        if (*xs)[i]%2 == 0 { // Or some other filtering function
             (*xs)[filterPos] = (*xs)[i]
         filterPos++
        }
    }
    (*xs) = (*xs)[:filterPos]
}

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

    fmt.Printf("initial a %+v\n", a)

    a.Filter()

    fmt.Printf("final a %+v\n", a)
}

Problem

I want to delete elements from a collection in an in-place manner. Consider the following snippet: ``` package main import "fmt" type Ints []int func (xs Ints) Filter() { for i := 0; i < len(xs); i++ { if xs[i]%2 == 0 { // Or some other filtering function xs = append(xs[:i], xs[i+1:]...) } fmt.Printf("i %+v\n", i) fmt.Printf("xs %+v\n", xs) } } func main() { a := Ints([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) fmt.Printf("initial a %+v\n", a) a.Filter() fmt.Printf("final a %+v\n", a) } ``` http://play.golang.org/p/1nL6Il2Gf1 The surprising result is: `final a [1 3 5 7 9 10 10 10 10 10]` I wonder how to do this. I'm pretty sure the receiver needs to be a pointer to `Ints`. But that messes up the code somewhat (adding `*xs` everywhere possibly with brackets) but more importantly it yields the same result.

Original source