亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何從 Golang 中的切片中刪除元素

如何從 Golang 中的切片中刪除元素

Go
jeck貓 2022-01-10 17:28:22
fmt.Println("Enter position to delete::")fmt.Scanln(&pos)new_arr := make([]int, (len(arr) - 1))k := 0for 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])}我正在使用此命令從切片中刪除一個元素,但它不起作用,請建議。
查看完整描述

3 回答

?
元芳怎么了

TA貢獻1798條經驗 獲得超7個贊

訂單事項


如果要保持數組有序,則必須將刪除索引右側的所有元素向左移動一位。希望這可以在 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 方法,清空一個包含 1 000 000 個元素的數組需要 224 秒,而這個只需要 0.06 ns。


這個答案不執行bounds-checking。它需要一個有效的索引作為輸入。這意味著大于或等于初始值的負值或索引len(s)將導致 Go 恐慌。


切片和數組索引為 0,刪除數組的第 n 個元素意味著提供輸入n-1。要刪除第一個元素,請調用remove(s, 0),要刪除第二個元素,請調用remove(s, 1),依此類推。


查看完整回答
反對 回復 2022-01-10
?
慕娘9325324

TA貢獻1783條經驗 獲得超4個贊

從 Slice 中刪除一個元素(這稱為“重新切片”):


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]

}


查看完整回答
反對 回復 2022-01-10
?
飲歌長嘯

TA貢獻1951條經驗 獲得超3個贊

這有點奇怪,但這里的大多數答案都是危險的,并且掩蓋了他們實際在做什么。查看有關從切片中刪除項目的原始問題,正在制作切片的副本,然后將其填充。這可確保當切片在您的程序中傳遞時,您不會引入細微的錯誤。


這是一些比較用戶在此線程和原始帖子中的答案的代碼。這是一個可以在其中處理此代碼的go playground。


基于附加的刪除

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: ", all) //[0 1 2 3 4 5 6 7 8 9]

    removeIndex := RemoveIndex(all, 5)


    fmt.Println("all: ", all) //[0 1 2 3 4 6 7 8 9 9]

    fmt.Println("removeIndex: ", removeIndex) //[0 1 2 3 4 6 7 8 9]


    removeIndex[0] = 999

    fmt.Println("all: ", all) //[999 1 2 3 4 6 7 9 9]

    fmt.Println("removeIndex: ", removeIndex) //[999 1 2 3 4 6 7 8 9]

}

在上面的示例中,您可以看到我創建了一個切片并用數字 0 到 9 手動填充它。然后我們從所有中刪除索引 5 并將其分配給刪除索引。但是,當我們現在打印所有內容時,我們看到它也已被修改。這是因為切片是指向底層數組的指針。寫出來,以removeIndex原因all被修改以及與該差值all是由不再從可到達的一個元件更長removeIndex。接下來我們改變一個值removeIndex,我們可以看到也all被修改了。Effective go對此進行了更詳細的介紹。


下面的例子我不會進入,但它為我們的目的做了同樣的事情。并且只是說明使用副本沒有什么不同。


package main


import (

    "fmt"

)


func RemoveCopy(slice []int, i int) []int {

    copy(slice[i:], slice[i+1:])

    return slice[:len(slice)-1]

}


func main() {

    all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9]

    removeCopy := RemoveCopy(all, 5)


    fmt.Println("all: ", all) //[0 1 2 3 4 6 7 8 9 9]

    fmt.Println("removeCopy: ", removeCopy) //[0 1 2 3 4 6 7 8 9]


    removeCopy[0] = 999

    fmt.Println("all: ", all) //[99 1 2 3 4 6 7 9 9]

    fmt.Println("removeCopy: ", removeCopy) //[999 1 2 3 4 6 7 8 9]

}

問題原始答案

查看原始問題,它不會修改要從中刪除項目的切片。對于大多數訪問此頁面的人來說,使該線程中的原始答案是迄今為止最好的。


package main


import (

    "fmt"

)


func OriginalRemoveIndex(arr []int, pos int) []int {

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

        } else {

            k++

        }

        i++

    }


    return new_arr

}


func main() {

    all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9]

    originalRemove := OriginalRemoveIndex(all, 5)


    fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9]

    fmt.Println("originalRemove: ", originalRemove) //[0 1 2 3 4 6 7 8 9]


    originalRemove[0] = 999

    fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9]

    fmt.Println("originalRemove: ", originalRemove) //[999 1 2 3 4 6 7 8 9]

}

如您所見,此輸出的行為符合大多數人的預期,并且可能是大多數人想要的。的修改originalRemove不會導致更改all,刪除索引并分配它的操作也不會導致更改!極好的!


這段代碼有點長,所以上面可以改成這樣。


一個正確的答案

package main


import (

    "fmt"

)


func RemoveIndex(s []int, index int) []int {

    ret := make([]int, 0)

    ret = append(ret, s[:index]...)

    return append(ret, s[index+1:]...)

}


func main() {

    all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9]

    removeIndex := RemoveIndex(all, 5)


    fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9]

    fmt.Println("removeIndex: ", removeIndex) //[0 1 2 3 4 6 7 8 9]


    removeIndex[0] = 999

    fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 9 9]

    fmt.Println("removeIndex: ", removeIndex) //[999 1 2 3 4 6 7 8 9]

}

幾乎與原始的刪除索引解決方案相同,但是我們在返回之前創建了一個新的切片來追加。


查看完整回答
反對 回復 2022-01-10
  • 3 回答
  • 0 關注
  • 580 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號