Home > Article > Backend Development > How to delete elements from a slice in go language
Deletion method: 1. Intercept the slice to delete the specified element, the syntax is "append(a[:i], a[i 1:]...)". 2. Create a new slice, filter out the elements to be deleted and assign them to the new slice. 3. Use a subscript index to record the position where a valid element should be; traverse all elements, and when a valid element is encountered, move it to index and increase the index by one; the final index position is the next position of all valid elements , and finally make an interception.
The operating environment of this tutorial: Windows 7 system, GO version 1.18, Dell G3 computer.
Go does not provide special syntax or functions for deleting slice elements. You need to use the characteristics of the slice itself to delete elements.
There are generally the following methods to delete specified elements in a slice. This article uses []int as an example to give the specific implementation.
1. Interception method (modify the original slice)
Here, interception of the slice is used to delete the specified element. Note that when deleting, the following elements will be moved forward, so the subscript i should be moved one position to the left.
// 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 }
2. Copy method (without changing the original slice)
This method is the easiest to understand. Reuse a slice and delete it. Elements are filtered out. The disadvantage is that it needs to open up space for another slice. The advantage is that it is easy to understand and does not modify the original 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 }
3. Shift method (modify the original slice)
##3.1 Method 1
Use a subscript index to record the position where the next valid element should be. Traverse all elements. When a valid element is encountered, move it to index and increase index by one. The final index position is the next position of all valid elements, and finally an interception is enough. This method will modify the original slice. This method can be seen as an improvement on the first method of interception, because each time an element needs to be moved, the performance is better.// DeleteSlice3 删除指定元素。 func DeleteSlice3(a []int, elem int) []int { j := 0 for _, v := range a { if v != elem { a[j] = v j++ } } return a[:j] }
3.2 Method 2
Creates a slice, but shares the underlying array of the original slice. In this way, there is no need to allocate additional memory space, and modifications can be made directly on the original 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 }
4. Performance comparison
Suppose our slice has 0 and 1, and we want to delete all 0. Here we test slices with lengths of 10, 100, and 1000 to compare the performance differences of the above four implementations. The generated slice function is as follows: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 }The benchmark test code is as follows:
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) } }The test results are as follows: The original slice length is 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.427sThe original slice length is 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/opThe original slice length is 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
5. Summary
Judging from the benchmark test results, the method with the best performance is the shift method, and the first implementation method is the better. The least performant and most commonly used method is the interception method. As the slice length increases, the performance difference between the above four deletion methods will become more obvious. In actual use, we can choose according to the different scenarios. If you cannot modify the original slice using the copy method, you can modify the original slice using the first implementation method of the shift method. 【Related recommendations:Go video tutorial, Programming teaching】
The above is the detailed content of How to delete elements from a slice in go language. For more information, please follow other related articles on the PHP Chinese website!