How to remove element of struct array in loop in golang

前端 未结 4 1684
谎友^
谎友^ 2020-12-29 06:01

Problem

I have array of structs:

type Config struct {
  Applications []Application
}

Note: Config - is a struct fo

相关标签:
4条回答
  • 2020-12-29 06:37

    This question is a bit older but I haven't found another answer on StackOverflow which mentions the following trick from the Slice Tricks to filter a list:

    b := a[:0]
    for _, x := range a {
        if f(x) {
            b = append(b, x)
        }
    }
    

    So in this case a function which deletes certain elements could look like this:

    func removeApplications(apps []Applications) []Applications {
        filteredApps := apps[:0]
        for _, app := apps {
            if !removeApp {
                filteredApps = append(filteredApps, app)
            }
        }
        return filteredApps
    }
    
    0 讨论(0)
  • 2020-12-29 06:46

    You are getting this error because you are doing a loop over a slice with an inital range of X length that became X-n because you remove some elements during loop.

    If you want to delete an item at a specific index from a slice, you can do it this way:

    sliceA = append(sliceA[:indexOfElementToRemove], sliceA[indexOfElementToRemove+1:]...)
    
    0 讨论(0)
  • 2020-12-29 06:49

    Quoting from the Slice Tricks page deleting the element at index i:

    a = append(a[:i], a[i+1:]...)
    // or
    a = a[:i+copy(a[i:], a[i+1:])]
    

    Note that if you plan to delete elements from the slice you're currently looping over, that may cause problems. And it does if the element you remove is the current one (or a previous element already looped over) because after the deletion all subsequent elements are shifted, but the range loop does not know about this and will still increment the index and you skip one element.

    You can avoid this by using a downward loop:

    for i := len(config.Applications) - 1; i >= 0; i-- {
        application := config.Applications[i]
        // Condition to decide if current element has to be deleted:
        if haveToDelete {
            config.Applications = append(config.Applications[:i],
                    config.Applications[i+1:]...)
        }
    }
    
    0 讨论(0)
  • 2020-12-29 06:51

    I think the simple way is

    var (
      slice = []int{1,2,3,4,5}
      pos int
    )
        for _, i := range slice {
            if i == 3 {
                slice = append(slice[:pos], slice[pos+1:]...)
                if pos > 0 {
                    pos = pos - 1
                }
                continue
            }
            pos++
        }
    

    here is... https://play.golang.org/p/pK3B5Mii9k

    0 讨论(0)
提交回复
热议问题