我有以下代码:
func TestRemoveElement(t *testing.T) {
nums := []int{3, 2, 2, 3}
result := removeElement(nums, 3)
if result != 2 {
t.Errorf("Expected 2, but it was %d instead.", result)
}
}
func removeElement(nums []int, val int) int {
for i, v := range nums {
if v == val {
nums = append(nums[:i], nums[i+1:]...)
}
}
return len(nums)
}
if
语句中的语句是按照此answer替换切片中元素的最常用方法。但是由于i+1
导致删除最后一个元素失败。即如果在最后一个元素中找到匹配项,则i+1
超出范围。有什么更好的方法来替换考虑最后元素的元素?
答案 0 :(得分:2)
您似乎正在尝试删除所有等于val
的元素。一种方法是将不等于val
的值复制到切片的开头:
func removeElement(nums []int, val int) []int {
j := 0
for _, v := range nums {
if v != val {
nums[j] = v
j++
}
}
return nums[:j]
}
返回新切片而不是返回长度。对来电者来说会更方便。
如果您只想删除等于val
的第一个元素,请使用以下代码:
func removeElement(nums []int, val int) []int {
for i, v := range nums {
if v == val {
return append(nums[:i], nums[i+1:]...)
}
}
return nums
}
答案 1 :(得分:1)
添加索引检查可以解决您的问题。 Copy
的效果优于append
,但您的原始附加版本仍可使用。 NVIDIA's cuDNN website
如果您正在处理切片,这是您的Go arsenal https://gist.github.com/xogeny/b819af6a0cf8ba1caaef
中的一个好页面另请注意,下面的函数不会更新您传入的切片,因此虽然它会打印删除的项目数,但原始切片不会删除这些项目。
func removeElement(nums []int, val int) int {
var i int
for {
if i == len(nums) {
break
}
if nums[i] == val {
nums = nums[:i+copy(nums[i:], nums[i+1:])]
i = 0
}
i++
}
return len(nums)
}
修改了也返回修改列表的removeElements
func removeElement(nums []int, val int) (numberOfItemsRemoved int, newArr []int) {
var i int
for {
if i == len(nums) {
break
}
if nums[i] == val {
nums = nums[:i+copy(nums[i:], nums[i+1:])]
i = 0
}
i++
}
return len(nums), nums
}
https://github.com/golang/go/wiki/SliceTricks
您还可以通过引用修改原始切片,以便不必返回
func removeElement(nums *[]int, val int) int {
var i int
for {
if i == len(*nums) {
break
}
slice := (*nums)
if slice[i] == val {
slice = slice[:i+copy(slice[i:], slice[i+1:])]
*nums = slice
i = 0
}
i++
}
return len(*nums)
}