How does one determine the position of an element present in slice?
I need something like the following:
type intSlice []int
func (slice intSlice) p
func index(slice []string, item string) int {
for i, _ := range slice {
if slice[i] == item {
return i
}
}
return -1
}
I had the same issue few months ago and I solved in two ways:
First method:
func Find(slice interface{}, f func(value interface{}) bool) int {
s := reflect.ValueOf(slice)
if s.Kind() == reflect.Slice {
for index := 0; index < s.Len(); index++ {
if f(s.Index(index).Interface()) {
return index
}
}
}
return -1
}
Use example:
type UserInfo struct {
UserId int
}
func main() {
var (
destinationList []UserInfo
userId int = 123
)
destinationList = append(destinationList, UserInfo {
UserId : 23,
})
destinationList = append(destinationList, UserInfo {
UserId : 12,
})
idx := Find(destinationList, func(value interface{}) bool {
return value.(UserInfo).UserId == userId
})
if idx < 0 {
fmt.Println("not found")
} else {
fmt.Println(idx)
}
}
Second method with less computational cost:
func Search(length int, f func(index int) bool) int {
for index := 0; index < length; index++ {
if f(index) {
return index
}
}
return -1
}
Use example:
type UserInfo struct {
UserId int
}
func main() {
var (
destinationList []UserInfo
userId int = 123
)
destinationList = append(destinationList, UserInfo {
UserId : 23,
})
destinationList = append(destinationList, UserInfo {
UserId : 123,
})
idx := Search(len(destinationList), func(index int) bool {
return destinationList[index].UserId == userId
})
if idx < 0 {
fmt.Println("not found")
} else {
fmt.Println(idx)
}
}
Sorry, there's no generic library function to do this. Go doesn't have a straight forward way of writing a function that can operate on any slice.
Your function works, although it would be a little better if you wrote it using range
.
If you happen to have a byte slice, there is bytes.IndexByte.
You can create generic function in idiomatic go way:
func SliceIndex(limit int, predicate func(i int) bool) int {
for i := 0; i < limit; i++ {
if predicate(i) {
return i
}
}
return -1
}
And usage:
xs := []int{2, 4, 6, 8}
ys := []string{"C", "B", "K", "A"}
fmt.Println(
SliceIndex(len(xs), func(i int) bool { return xs[i] == 5 }),
SliceIndex(len(xs), func(i int) bool { return xs[i] == 6 }),
SliceIndex(len(ys), func(i int) bool { return ys[i] == "Z" }),
SliceIndex(len(ys), func(i int) bool { return ys[i] == "A" }))
You could write a function;
func indexOf(element string, data []string) (int) {
for k, v := range data {
if element == v {
return k
}
}
return -1 //not found.
}
This returns the index of a character/string if it matches the element. If its not found, returns a -1.
There is no library function for that. You have to code by your own.