【问题标题】:How to remove an item from a slice repeatedly? [duplicate]如何重复从切片中删除项目? [复制]
【发布时间】:2021-09-21 00:07:58
【问题描述】:

我想从一个数组创建多个切片。一个切片,每个切片缺少一个元素。我正在使用此代码(playground):

nums := []int{1,2,3}
for i := 0; i < len(nums); i++ {
    fmt.Println(append(nums[:i], nums[i+1:]...))
}

我期待收到

[2 3]
[1 3]
[1 2]

但是我收到了

[2 3]
[2 3]
[2 3]

为什么会这样?

【问题讨论】:

  • 所以,我想我总是附加到nums。但是我该如何防止呢?
  • append(nums[:i], nums[i+1:]...) 修改切片的底层数组 inside 的值(如果它们适合),因此第一次迭代将 nums 底层数组更改为 [2 3 3],依此类推开。
  • 我想这会对你有所帮助stackoverflow.com/questions/35920534/…

标签: go slice


【解决方案1】:

As mkopriva correctly pointed out,您的程序的输出与您的预期不同,因为append 产生的所有切片共享相同的底层数组。您需要以某种方式将这些切片与切片 nums 的底层数组解耦。

一种可行的方法确实是使用copy,就像您在your answer 中所做的那样。有一个更简洁的替代方案,尽管对于未经训练的人来说可能不太清楚。

您可以使用nums[:i:i]full-slice expression,又名三索引切片)作为append 的第一个参数,而不是诉诸copy

nums := []int{1,2,3}
for i := 0; i < len(nums); i++ {
    fmt.Println(append(nums[:i:i], nums[i+1:]...))
}

生成的切片将与切片nums 的底层数组解耦,您将获得所需的输出:

[2 3]
[1 3]
[1 2]

(Playground)

【讨论】:

    【解决方案2】:

    非常感谢您向我指出这一点。这是我目前的解决方案。它只是复制我正在处理的数组 (playground)

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        nums := []int{1,2,3}
            for i := 0; i < len(nums); i++ {
                cpy := make([]int, len(nums))
                copy(cpy, nums)
                fmt.Println(append(cpy[:i], cpy[i+1:]...))
            }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 2013-09-04
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多