如何重复从切片中删除项目?

How to remove an item from a slice repeatedly?

我想从一个数组创建多个切片。一片,每片缺少一个元素。我正在使用此代码 (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]

这是为什么?

非常感谢您向我指出这一点。这是我目前的解决方案。它只是复制我正在处理的数组 (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:]...))
        }
}

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

的底层数组分离

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

而不是求助于 copy,您可以使用 nums[:i:i]full-slice expression、a.k.a。三索引切片) 作为 append:

的第一个参数
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)

从 Go 1.18 开始,您可以使用 golang.org/x/exp/slices package 中的函数 CloneDelete 以更具可读性的方式实现相同的结果:

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

(Playground)