Consider the following example:
package main
import (
"fmt"
"sort"
)
func main() {
var n int
var a sort.IntSlice
a = append(a, 23)
a = append(a, 3)
a = append(a, 10)
sort.Sort(a)
fmt.Println(a)
n = sort.SearchInts(a, 1)
fmt.Println(n)
n = sort.SearchInts(a, 3)
fmt.Println(n)
}
http://play.golang.org/p/wo4r43Zghv
And the result is:
[3 10 23]
0
0
How am I supposed to know if the number is present in the slice or not, when both the first element and the nonexistent element return 0 as index?
Update Note that the index can also be greater than the length of the slice so the proper way to find if an element is present in the slice is:
num := 1
n = sort.SearchInts(a, num)
if n < len(a) && a[n] == num {
// found
}
Check whether the number you were looking for actually lives at the returned index. The binary search routines in sort
are supposed to find the index where a value can be inserted if it's not already present.
E.g. a search for 100 in the slice in your example will return 3 because the value must be appended to the slice.
the call
Search(len(data), func(i int) bool { return data[i] >= 23 })
returns the smallest index i such thatdata[i] >= 23
. If the caller wants to find whether 23 is in the slice, it must testdata[i] == 23
separately.
SearchInts
searches for x in a sorted slice of ints and returns the index as specified by Search. SearchInts
calls Search
with a function:
func(i int) bool { return a[i] >= x }
Quoting from the Search doc:
Search uses binary search to find and return the smallest index i in [0, n) at which f(i) is true, assuming that on the range [0, n), f(i) == true implies f(i+1) == true. That is, Search requires that f is false for some (possibly empty) prefix of the input range [0, n) and then true for the (possibly empty) remainder; Search returns the first true index. If there is no such index, Search returns n. Search calls f(i) only for i in the range [0, n).
So basically you'll get back an index where the number you searched for should be inserted so the slice remains sorted.
Just check if at the returned index the number in the slice is identical to the one you searched for.
It may seem a functionally strange feature but it's documented :
For instance, given a slice data sorted in ascending order, the call Search(len(data), func(i int) bool { return data[i] >= 23 }) returns the smallest index i such that data[i] >= 23.
The obvious solution is also documented :
If the caller wants to find whether 23 is in the slice, it must test data[i] == 23 separately.
This snippet is from the documentation:
x := 23
i := sort.Search(len(data), func(i int) bool { return data[i] >= x })
if i < len(data) && data[i] == x {
// x is present at data[i]
} else {
// x is not present in data,
// but i is the index where it would be inserted.
}
http://golang.org/pkg/sort/#Search
So you have to check i < len(data) && data[i] == x
like you suggest.