I have 2 go functions like following
func removeL2McEntry(a []api.L2McEntry, index int) []api.L2McEntry {
a = append(a[:index], a[index+1:]...)
element
return a[:len(a)]
}
func removeVlagBasedGroup(a []api.VlanPortBased, index int) []api.VlanPortBased {
a = append(a[:index], a[index+1:]...)
return a[:len(a)]
}
As you can see, both functions are doing the same work. But I need to separate them because the outputs and the inputs of the functions are different type.
I have tried:
func removeSlice(a interface{}, idx int) interface{} {
switch v := a.(type) {
case []string:
v = append(v[:idx], v[idx+1:]...)
fmt.Println("is ary", v)
return v[:len(v)]
case []int:
v = append(v[:idx], v[idx+1:]...)
fmt.Println("is ary", v)
return v[:len(v)]
default:
}
return nil
}
But there is too many repetitive code in this way. Is there any way to make it just one function and reduce the repetitive code?
Thanks in advance.
As Adrian noted, removing an element from a slice is one line of code, in general:
a = append(a[:i], a[i+1]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]
It's not really worth writing a function for it, just use this code snippet where needed.
If you do need to create a function that can handle any slice types, it can be created using reflection. But when using it, you will have to use a type assertion on the result, as the function can only return a static type of interface{}
. It will also be slower than using the above snippet on your concrete slice value!
The above remove steps can be "reproduced" using the reflect
package. Slicing is the Value.Slice()
method, and the append operation is the reflect.AppendSlice()
function.
This is how it could look like (types and bound checks omitted):
func remove(s interface{}, i int) interface{} {
v := reflect.ValueOf(s)
return reflect.AppendSlice(v.Slice(0, i), v.Slice(i+1, v.Len())).Interface()
}
Testing it:
is := []int{0, 1, 2, 3}
is = remove(is, 2).([]int)
fmt.Printf("%#v\n", is)
ss := []string{"0", "1", "2", "3"}
ss = remove(ss, 2).([]string)
fmt.Printf("%#v\n", ss)
Output (try it on the Go Playground):
[]int{0, 1, 3}
[]string{"0", "1", "3"}
But again: I don't advise anyone to use this (although working) code, just remove the element directly with the original snippet.