【问题标题】:How to remove element of struct array in loop in golang如何在golang的循环中删除结构数组的元素
【发布时间】:2015-05-14 09:01:55
【问题描述】:

问题

我有结构数组:

type Config struct {
  Applications []Application
}

注意:Config - 是 json.Decode 的结构。

config = new(Config)
_ = decoder.Decode(&config)

在循环中,我通过键删除了一些条件和元素。

for i, application := range config.Applications {
  if i == 1 {
    config.Applications = _removeApplication(i, config.Applications)
  }
}

func _removeApplication(i int, list []Application) []Application {
  if i < len(list)-1 {
    list = append(list[:i], list[i+1:]...)
  } else {
    log.Print(list[i].Name)
    list = list[:i]
  }

  return list
}

但我总是有“超出范围”的错误。从结构数组中按键删除元素的最佳方法是什么?

【问题讨论】:

    标签: arrays struct go slice


    【解决方案1】:

    引用Slice Tricks页面删除索引i处的元素:

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

    请注意,如果您打算从当前循环的切片中删除元素,则可能会导致问题。如果您删除的元素是当前元素(或已循环的前一个元素),它会这样做,因为删除后所有后续元素都会移动,但range 循环不知道这一点,并且仍然会增加索引并且您跳过一个元素。

    您可以通过使用向下循环来避免这种情况:

    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:]...)
        }
    }
    

    【讨论】:

    • @Michael ... 告诉您有一个切片,您想将其传递为 variadic 参数的值。 append() 有一个可变参数,通常由 枚举 元素调用,但在这种情况下,我们通过 拥有 切片中的元素和 passing 那个切片,我们希望切片的元素是可变参数的值(我们不希望切片本身是可变参数的单个元素)。
    • 从循环中中断,因为你想删除单个元素?
    【解决方案2】:

    您收到此错误是因为您正在对初始范围为 X 长度的切片执行循环,该切片变为 X-n,因为您在循环期间删除了一些元素。

    如果要从切片中删除特定索引处的项目,可以这样做:

    sliceA = append(sliceA[:indexOfElementToRemove], sliceA[indexOfElementToRemove+1:]...)
    

    【讨论】:

      【解决方案3】:

      这个问题有点老了,但我在 StackOverflow 上没有找到另一个答案,其中提到了 Slice Tricks 中的以下技巧来过滤列表:

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

      所以在这种情况下,删除某些元素的函数可能如下所示:

      func removeApplications(apps []Applications) []Applications {
          filteredApps := apps[:0]
          for _, app := apps {
              if !removeApp {
                  filteredApps = append(filteredApps, app)
              }
          }
          return filteredApps
      }
      

      【讨论】:

        【解决方案4】:

        我认为简单的方法是

        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++
            }
        

        这里是... https://play.golang.org/p/pK3B5Mii9k

        【讨论】:

          【解决方案5】:

          要从结构中删除特定切片,我们需要运行一个 for 循环来找到该特定切片并将其删除

          例如:

          type variable struct {
          Id      int    `json:"id"`
          Message string `json:"message"`
          }
          
          var mssg = []variable{
          {Id: 1, Message: "success"},
          {Id: 2, Message: "failed"}
          }
          for i, a := range mssg {
              if a.Message == "success" {
                  mssg = append(mssg[:i], mssg[i+1:]...)
                  fmt.Println(mssg)
              }
          

          【讨论】:

            猜你喜欢
            • 2010-12-29
            • 1970-01-01
            • 2013-05-04
            • 2012-02-15
            • 2014-09-08
            • 2021-09-05
            • 2018-05-24
            • 1970-01-01
            相关资源
            最近更新 更多