Цикл над срезом и выйти, если он не существует

#go

# #Вперед

Вопрос:

Я пытаюсь создать цикл, который будет выполнять следующее:

Цикл будет выполнять поиск по всем элементам фрагмента один за другим:

  1. если буква не существует, перейдите к следующему элементу цикла.
  2. Если буква существует, выйдите из цикла.
  3. если в фрагменте нет совпадений, завершите работу в ОС.

ниже приведен код, который я пытаюсь:

 userDefinedletter := "g"
letters := []string{"a", "b", "c", "d"}
    for _, a := range letters{
        if a != userDefinedletter {
            continue
        } else if a == userDefinedletter {
            fmt.Printf("letter %s found. n", userDefinedletter)
            break
        } else {
            fmt.Println("letter not found in the slice")
            os.Exit(1)
        }
    }
 

Ответ №1:

Установите для переменной значение false. В цикле установите для переменной значение true, если буква найдена. После цикла проверьте переменную, чтобы определить, была ли найдена буква:

 ok := false
for _, a := range letters {
    if a == userDefinedletter {
        ok = true
        break
    }
}

if ok {
    fmt.Printf("letter %s found. n", userDefinedletter)
} else {
    fmt.Println("letter not found in the slice")
    os.Exit(1)
}
 

Комментарии:

1. Это то, что мне было нужно! Спасибо

Ответ №2:

Вы движетесь в правильном направлении, но для такой маленькой функции вы сделали ненужное вложение, которого вы могли бы избежать.

 func present(slice []string, find string) bool {
        for _, s := range slice {
                if s == find {
                        return true
                }
        }
        return false
}

func main() {
        slice := []string{"a", "b", "c", "d"}
        find := "g"
        if !present(slice, find) {
                os.Exit(1)
        }
        fmt.Printf("Found: %s in slice: %vn", find, slice)
}
 

Комментарии:

1. Это хорошо работает! спасибо .. но возможно ли это сделать без функции?

2. Я оставлю вопрос вам. Я просто хотел дать вам направление. Будет лучше, если вы узнаете это сами!

Ответ №3:

Я думаю, что мы можем легко решить вашу проблему следующим образом: просто проверьте, находится ли буква на слайде или нет, и получите позицию, когда буква включена в срез.

 package main

import (
    "fmt"
    "strings"
)

func main() {
    slice := []string{"a", "b", "c", "d"}
    find := "g"
    if pos := strings.Index(strings.Join(slice, ""), find); pos != -1 {
        fmt.Println("Slice does not contain letter")
    } else {
        fmt.Println("Letter is in slice and position is: ", pos)
    }
}
 

Вы можете быстро протестировать приведенный выше код по этой ссылке онлайн: https://play.golang.org /

Комментарии:

1. Зачем усложнять такую простую задачу. Объединение фрагмента строки и использование strings.Index для поиска индекса — это то же самое, что поиск элемента с помощью цикла, но с дополнительными операциями. Почему?

2. Зачем вам нужно снова выполнять простую работу, когда библиотека уже это сделала? Просто нужно понять, что делает библиотека, и использовать ее. Мой код короткий и чистый. И вы можете повторно реализовать функцию, когда ссылаетесь на нее в github: golang.org/src/strings/strings.go

3. Вам не нужно давать ссылки; все, кто использует Go, знают, что пакет с открытым исходным кодом. Суть в том, что вы объединили строки и все еще защищаете подход. Просто чтобы использовать функцию из пакета strings, вы выполняете ненужные операции, чтобы вы могли использовать strings.Index . ПРИМЕЧАНИЕ: ЭТО ПРОСТОЙ ЛИНЕЙНЫЙ ПОИСК.

4. Здесь: pastebin.pl/view/9f2371e4 (PresentTwo — это ваша функция, PresentOne — это функция, которую я написал). Теперь посмотрите сравнительный анализ. Ваш код занимает 4 раза больше времени, но используйте 8B для каждой операции и делает 1 выделение / операцию, где в качестве более простой функции это 0 B / op и 0 alloc / op. Пожалуйста, не комментируйте без сравнительного анализа. BenchmarkPresentTwo-8 10967002 108 ns/op 8 B/op 1 allocs/op ——————————- // BenchmarkPresentOne-8 35317174 32.7 ns/op 0 B/op 0 allocs/op

5. Хорошая работа, чувак, спасибо за объяснение очень подробно для меня. Да, вы правы, мой подход усложняет эту проблему. Кстати, не могли бы вы поделиться со мной документом для сравнительного анализа golang.

Ответ №4:

Поскольку буквы расположены в отсортированном порядке, вы можете использовать sort.SearchStrings:

 i := sort.SearchStrings(letters, userDefinedletter)

if i < len(letters) amp;amp; letters[i] == userDefinedletter {
    fmt.Printf("letter %s found. n", userDefinedletter)

} else {
    fmt.Println("letter not found in the slice")
    os.Exit(1)
}
 

Комментарии:

1. Не думайте, что он уже отсортирован, если он не упомянут.