fmt.Println("Enter position to delete::")
fmt.Scanln(&pos)

new_arr := make([]int, (len(arr) - 1))
k := 0
for i := 0; i < (len(arr) - 1); {
    if i != pos {
        new_arr[i] = arr[k]
        k++
        i++
    } else {
        k++
    }
}

for i := 0; i < (len(arr) - 1); i++ {
    fmt.Println(new_arr[i])
}

我正在使用这个命令从切片中删除一个元素,但它不起作用,请建议。


当前回答

我采用下面的方法切片删除项目。这有助于提高其他人的可读性。也是不可变的。

func remove(items []string, item string) []string {
    newitems := []string{}

    for _, i := range items {
        if i != item {
            newitems = append(newitems, i)
        }
    }

    return newitems
}

其他回答

顺序很重要

如果你想要保持数组的有序,你必须将删除索引右边的所有元素向左移动一个单位。希望在Golang中可以轻松做到这一点:

func remove(slice []int, s int) []int {
    return append(slice[:s], slice[s+1:]...)
}

然而,这是低效的,因为您可能最终要移动所有的元素,这是昂贵的。

顺序并不重要

如果你不关心顺序,你可以更快地将要删除的元素替换为片末尾的元素,然后返回第n-1个元素:

func remove(s []int, i int) []int {
    s[i] = s[len(s)-1]
    return s[:len(s)-1]
}

使用reslicing方法,清空一个包含100万个元素的数组需要224秒,而这个方法只需要0.06ns。

这个答案不执行边界检查。它需要一个有效的索引作为输入。这意味着大于或等于初始len(s)的负值或下标将导致Go panic。

切片和数组是0索引,删除数组的第n个元素意味着提供输入n-1。要删除第一个元素,调用remove(s, 0),要删除第二个元素,调用remove(s, 1),依此类推。

从切片中移除一个元素(这称为“重新切片”):

package main

import (
    "fmt"
)

func RemoveIndex(s []int, index int) []int {
    return append(s[:index], s[index+1:]...)
}

func main() {
    all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    fmt.Println(all) //[0 1 2 3 4 5 6 7 8 9]
    all = RemoveIndex(all, 5)
    fmt.Println(all) //[0 1 2 3 4 6 7 8 9]
}

因为Slice是由数组支持的因为你不可能从数组中删除一个元素而不重新洗牌内存,我不想写这么难看的代码;下面是一个伪代码,用于保存已删除项的索引;基本上,我想要一个有序的切片,即使在删除后位置也很重要

type ListSlice struct {
  sortedArray []int
  deletedIndex map[int]bool
}
func lenSlice(m ListSlice)int{
    return len(m.sortedArray)
}
func deleteSliceElem(index int,m ListSlice){
    m.deletedIndex[index]=true
}
func getSliceElem(m ListSlice,i int)(int,bool){
    _,deleted :=m.deletedIndex[i]
    return m.sortedArray[i],deleted
}
for i := 0; i < lenSlice(sortedArray); i++ {
        
        k,deleted := getSliceElem(sortedArray,i)
        if deleted {continue}
        ....
        deleteSliceElem(i,sortedArray)

}

m := ListSlice{sortedArray: []int{5, 4, 3},deletedIndex: make(map[int]bool) }
...

从切片包中使用Delete(实验性的,从Go 1.18开始可用):

slice := []int{1, 2, 3, 4}
slice = slices.Delete(slice, 1, 2)
fmt.Println(slice) // [1 3 4]

去游乐场的例子

片。Delete(s, i, j)从s中删除元素s[i:j]

即从索引I到索引j的元素 如果你还记得区间的数学符号:[i,j)

注意两点:

Delete修改原始片的内容 你需要重新分配切片,否则它会有错误的长度

for index, item := range movies{
    if item.ID == "123"{
        movies = append(movies[:index], movies[index+1:]...)
        break
    }
}