簡單介紹Golang切片刪除指定元素的三種方法
導讀 | Go語言並沒有提供用於刪除元素的語法或介面,而是透過利用切片本身的特性來刪除元素—追加元素,這篇文章主要給大家介紹了關於Golang切片刪除指定元素的三種方法,需要的朋友可以參考下 |
Go 並沒有提供刪除切片元素專用的語法或函式,需要使用切片本身的特性來刪除元素。
刪除切片指定元素一般有如下幾種方法,本文以 []int 為例給出具體實現。
這裡利用對 slice 的擷取刪除指定元素。注意刪除時,後面的元素會前移,所以下標 i 應該左移一位。
// DeleteSlice1 刪除指定元素。 func DeleteSlice1(a []int, elem int) []int { for i := 0; i < len(a); i++ { if a[i] == elem { a = append(a[:i], a[i+1:]...) i-- } } return a }
這種方法最容易理解,重新使用一個 slice,將要刪除的元素過濾掉。缺點是需要開闢另一個 slice 的空間,優點是容易理解,而且不會修改原 slice。
// DeleteSlice2 刪除指定元素。 func DeleteSlice2(a []int, elem int) []int { tmp := make([]int, 0, len(a)) for _, v := range a { if v != elem { tmp = append(tmp, v) } } return tmp }
利用一個下標 index,記錄下一個有效元素應該在的位置。遍歷所有元素,當遇到有效元素,將其移動到 index 且 index 加一。最終 index 的位置就是所有有效元素的下一個位置,最後做一個擷取就行了。這種方法會修改原來的 slice。
該方法可以看成對第一種方法擷取法的改進,因為每次指需移動一個元素,效能更加。
// DeleteSlice3 刪除指定元素。 func DeleteSlice3(a []int, elem int) []int { j := 0 for _, v := range a { if v != elem { a[j] = v j++ } } return a[:j] }
建立了一個 slice,但是共用原始 slice 的底層陣列。這樣也不需要額外分配記憶體空間,直接在原 slice 上進行修改。
// DeleteSlice4 刪除指定元素。 func DeleteSlice4(a []int, elem int) []int { tgt := a[:0] for _, v := range a { if v != elem { tgt = append(tgt, v) } } return tgt }
假設我們的切片有 0 和 1,我們要刪除所有的 0。
這裡分別對長度為 10、100、1000 的切片進行測試,來上下上面四種實現的效能差異。
生成切片函式如下:
func getSlice(n int) []int { a := make([]int, 0, n) for i := 0; i < n; i++ { if i%2 == 0 { a = append(a, 0) continue } a = append(a, 1) } return a }
基準測試程式碼如下:
func BenchmarkDeleteSlice1(b *testing.B) { for i := 0; i < b.N; i++ { _ = DeleteSlice1(getSlice(10), 0) } } func BenchmarkDeleteSlice2(b *testing.B) { for i := 0; i < b.N; i++ { _ = DeleteSlice2(getSlice(10), 0) } } func BenchmarkDeleteSlice3(b *testing.B) { for i := 0; i < b.N; i++ { _ = DeleteSlice3(getSlice(10), 0) } } func BenchmarkDeleteSlice4(b *testing.B) { for i := 0; i < b.N; i++ { _ = DeleteSlice4(getSlice(10), 0) } }
測試結果如下:
原切片長度為 10:
go test -bench=. main/slice goos: windows goarch: amd64 pkg: main/slice cpu: Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz BenchmarkDeleteSlice1-8 17466486 65.07 ns/op BenchmarkDeleteSlice2-8 14897282 85.22 ns/op BenchmarkDeleteSlice3-8 21952129 50.78 ns/op BenchmarkDeleteSlice4-8 22176390 54.68 ns/op PASS ok main/slice 5.427s
原切片長度為 100:
BenchmarkDeleteSlice1-8 1652146 762.1 ns/op BenchmarkDeleteSlice2-8 2124237 578.4 ns/op BenchmarkDeleteSlice3-8 3161318 359.9 ns/op BenchmarkDeleteSlice4-8 2714158 423.7 ns/op
原切片長度為 1000:
BenchmarkDeleteSlice1-8 56067 21915 ns/op BenchmarkDeleteSlice2-8 258662 5007 ns/op BenchmarkDeleteSlice3-8 432049 2724 ns/op BenchmarkDeleteSlice4-8 325194 3615 ns/op
從基準測試結果來看,效能最佳的方法是移位法,其中又屬第一種實現方式較佳。效能最差的也是最常用的方法是擷取法。隨著切片長度的增加,上面四種刪除方式的效能差異會愈加明顯。
實際使用時,我們可以根據不用場景來選擇。如不能修改原切片使用複製法,可以修改原切片使用移位法中的第一種實現方式。
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2906345/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python 中刪除列表元素的三種方法Python
- Golang切片的三種簡單使用方式及區別Golang
- 簡單介紹Golang列印複雜結構體的兩種方法Golang結構體
- <svg>元素簡單介紹SVG
- golang-切片slice的基本介紹Golang
- 簡單介紹Python drop方法刪除列之inplace引數例項Python
- JavaScript 刪除陣列指定元素JavaScript陣列
- jQuery刪除具有指定文字的li元素jQuery
- Array · 刪除陣列中指定的元素陣列
- golang 切片簡單運用Golang
- Word中怎麼刪除空白頁?這三種方法簡單高效專業
- 簡單介紹mysql如何刪除資料表和關聯的資料表刪除詳情MySql
- 簡單介紹vscode除錯container中的程式的方法步驟VSCode除錯AI
- 簡單介紹Lua中三種迴圈語句的使用
- 簡單介紹apache虛擬主機配置的三種方式Apache
- Python刪除列表元素的3種方法,你都會嗎?Python
- 簡單介紹四種Python 列表反轉顯示的方法Python
- Golang中map的三種宣告方式和簡單實現增刪改查Golang
- Html 5.2 的簡單介紹及新增元素 <dialog></dialog>HTML
- ArrayList元素的刪除(4種函式)函式
- 簡單介紹NMS的實現方法
- 簡單介紹PostgreSQL解析URL的方法SQL
- 簡單介紹oracle重置序列的方法Oracle
- 簡單介紹java中的equals()方法Java
- 簡單介紹三層交換
- CSRF簡單介紹及利用方法
- 簡單介紹python輸出列表元素的所有排列形式Python
- 簡單介紹如何使用Bazel構建Golang程式Golang
- for迴圈無法刪除陣列所有指定元素陣列
- Python列表刪除元素的方法有哪些?Python
- 【leetcode】27. Remove Element 刪除陣列指定值的元素LeetCodeREM陣列
- 分散式鎖簡單入門以及三種實現方式介紹分散式
- iPhone簡訊刪除怎麼恢復?恢復iPhone簡訊的兩種簡單方法推薦iPhone
- 簡單介紹MySQL索引失效的幾種情況MySql索引
- STL.vector容器刪除單個元素、部分元素、全部元素
- PHP從陣列中刪除元素的方法PHP陣列
- Webpack 的簡單介紹Web
- AOP的簡單介紹