Ah, my last post had a small mistake. A small modification to upper should
be all you need. The function should use >= instead of >. See below.

        upper := sort.Search(len(haystack), func(i int) bool {
return haystack[i].name >= needle.name
})

On Tue, Oct 11, 2022, 7:38 AM K. Alex Mills <k.alex.mi...@gmail.com> wrote:

> sort.Search runs binary search. It's only guaranteed to work when you
> provide it with a function which is monotonic -- true at index i implies
> true at all indices greater than i.
>
> Your loop style search does not provide a monotonic function, whereas your
> "upper" function is monotonic. However, since "lower" is also not monotonic
> I'd question whether the first approach would continue to work on larger
> arrays. When testing binary search algorithms, it's important to use arrays
> of many varying sizes, since the edge cases often don't appear on smaller
> length lists.
>
> In any case, on a sorted list, "upper" should be the only function you
> need to determine whether the needle can be found in the list. sort.Search
> guarantees that the index it returns is the first index where the monotonic
> function changes its value. If the needle you're looking for is in the
> haystack, the value at that index will be the needle itself.
>
> On Tue, Oct 11, 2022, 7:22 AM 'ljh' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
>> Hi community,
>>
>> I used sort.Search on a sorted slice in below code started at Line 36,
>> and it worked.
>>
>> I also tried to call sort.Search in a loop, started at Line 53. It does
>> not seem to work. How can I correct the loop version?
>>
>> Thanks
>>
>> ---
>>
>> package main
>>
>> import (
>> "log"
>> "sort"
>> )
>>
>> type T struct {
>> name string
>> }
>>
>> func main() {
>> log.SetFlags(log.LstdFlags | log.Llongfile)
>>
>> haystack := []T{
>> // {name: "apple",  },
>> {name: "compote", }, //dup
>> {name: "orange", },
>> {name: "compote", }, //dup
>> }
>>
>> sort.Slice(haystack, func(i, j int) bool {
>> if haystack[i].name < haystack[j].name {
>> return true
>> } else {
>> return false
>> }
>> })
>>
>> for _, t := range haystack {
>> log.Println("sorted", t)
>> }
>>
>> needle := T{name: "compote"}
>>
>> // Style 1: ok, lower upper bounds style // Line 36
>> /*
>> lower := sort.Search(len(haystack), func(i int) bool {
>> return haystack[i].name == needle.name
>> })
>>
>> upper := sort.Search(len(haystack), func(i int) bool {
>> return haystack[i].name > needle.name
>> })
>>
>> if lower != len(haystack) {
>> for i := lower; i != upper; i++ {
>> log.Println("found", i, haystack[i])
>> }
>> }
>> */
>>
>> // Style 2: error, loop style // Line 53
>> for index := 0; index < len(haystack); index++ {
>> ret := sort.Search(len(haystack[index:]), func(i int) bool {
>> return haystack[index:][i].name == needle.name })
>>
>> log.Println(index, ret)
>>
>> if ret < len(haystack) {
>> index += ret
>> log.Println("found", index, haystack[index])
>> }
>> }
>> }
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/tencent_659665C8263F2DF81643C2B86412244F3105%40qq.com
>> <https://groups.google.com/d/msgid/golang-nuts/tencent_659665C8263F2DF81643C2B86412244F3105%40qq.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CALJzkY9O5F_trJAhp8i8jSdVOb7wf%2Brz06JEHu8GXoQuVPQkVQ%40mail.gmail.com.

Reply via email to