Skip to content

Instantly share code, notes, and snippets.

@tappoz
Last active June 3, 2019 15:31
Show Gist options
  • Select an option

  • Save tappoz/41f975261dc63d46431990bc31cb5bf4 to your computer and use it in GitHub Desktop.

Select an option

Save tappoz/41f975261dc63d46431990bc31cb5bf4 to your computer and use it in GitHub Desktop.

Revisions

  1. tappoz revised this gist Jun 3, 2019. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions golang-slice-in-place-removal.md
    Original file line number Diff line number Diff line change
    @@ -43,8 +43,8 @@ func FindAndRemoveFromFooSliceInPlace(iFilter int, inSl *[]FooItem) *FooItem {

    // check these docs: https://github.com/golang/go/wiki/SliceTricks#delete
    pointedInSl = append(pointedInSl[:idx], pointedInSl[idx+1:inLen]...)
    pointedInSl = pointedInSl[:inLen-1]
    *inSl = pointedInSl // assigning the new slice to the pointed value before returning
    pointedInSl = pointedInSl[:inLen-1] // redundant instruction, but it gives the ideas
    *inSl = pointedInSl // assigning the new slice to the pointed value before returning

    return &elem
    }
  2. tappoz created this gist Jun 3, 2019.
    78 changes: 78 additions & 0 deletions golang-slice-in-place-removal.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    Run the following code with: `go test -v -run TestFooInPlace`

    ```go
    package foo

    import (
    "fmt"
    "log"
    "math/rand"
    "testing"
    )

    type FooItem struct {
    Id int
    Category string
    Value float64
    }

    const minRand = 0
    const maxRand = 10

    const maxSliceLen = 3

    var inFooSlice []FooItem

    func init() {
    for i := 1; i <= maxSliceLen; i++ {
    inFooSlice = append(inFooSlice, FooItem{
    Id: i,
    Category: "FooCat",
    Value: minRand + rand.Float64()*(maxRand-minRand),
    })
    }
    }

    // use a pointer for the input slice so then it is changed in-place
    func FindAndRemoveFromFooSliceInPlace(iFilter int, inSl *[]FooItem) *FooItem {
    pointedInSl := *inSl // dereference the pointer so then we can use `append`
    inLen := len(pointedInSl)
    for idx, elem := range pointedInSl {
    if elem.Id == iFilter {
    log.Printf("Loop ID %v", idx)

    // check these docs: https://github.com/golang/go/wiki/SliceTricks#delete
    pointedInSl = append(pointedInSl[:idx], pointedInSl[idx+1:inLen]...)
    pointedInSl = pointedInSl[:inLen-1]
    *inSl = pointedInSl // assigning the new slice to the pointed value before returning

    return &elem
    }
    }
    return nil
    }

    func TestFooInPlace(t *testing.T) {
    originalLegth := len(inFooSlice)
    fmt.Printf("\nOriginal (PRE) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(originalLegth)
    fmt.Println(cap(inFooSlice))

    idFilter := 1

    fePtr := FindAndRemoveFromFooSliceInPlace(idFilter, &inFooSlice)

    fmt.Printf("\nOriginal (POST) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    fmt.Printf("\nFiltered element\n")
    fmt.Println(*fePtr)

    if originalLegth != len(inFooSlice)+1 {
    t.Errorf("Length mismatch: the original length %v, the current length %v", originalLegth, len(inFooSlice))
    }
    }
    ```