删除切片中的最后一个元素

时间:2017-09-04 23:11:14

标签: go slice

我有以下代码:

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超出范围。有什么更好的方法来替换考虑最后元素的元素?

2 个答案:

答案 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)
}

使用示例https://goplay.space/#1yfhTkZC4o