Как искать элемент в срезе и сравнивать его с переменной

#go #if-statement #slice

#Вперед #if-оператор #нарезать

Вопрос:

Я хочу создать простую логику:

 if stringCatchedFromBodyJSON != stringStoragedInMySlice {
//Do stuff
}else{
//Do more stuff
}
 

Я пробовал:

 if !storage.Contains(database.USER, stringCatchedFromBodyJSON){ //Says ".Contains" isn't declared}
if stringCatchedFromBodyJSON != dataBaseUsers { //Force databaseUsers to string = "" intead of comparing}
 

Создана функция для возврата true, если stringCatchedFromBodyJSON равно stringStoragedInMySlice, но программа вылетает при вводе функции:

 if itemExists(storage, stringCatchedFromBodyJSON) == true {}

func itemExists(arrayType interface{}, item interface{}) bool {
    arr := reflect.ValueOf(arrayType)

    if arr.Kind() != reflect.Array {
        panic("Invalid data-type")
    }

    for i := 0; i < arr.Len(); i   {
        if arr.Index(i).Interface() == item {
            return true
        }
    }

    return false
}
 

У меня есть этот arraylist:

 func arrayList() {
    storage = append(storage, Database{USER: "Max", PASSWORD: "1234"})
    storage = append(storage, Database{USER: "Rob", PASSWORD: "5678"})
    storage = append(storage, Database{USER: "Lee", PASSWORD: "9101"})
    storage = append(storage, Database{USER: "Joe", PASSWORD: "1213"})
    storage = append(storage, Database{USER: "May", PASSWORD: "1415"})
}
 

И эта структура:

 type Database struct {
    USER     string `json:"user"`
    PASSWORD string `json:"password"`
}
 

Мне удалось добавить нового «пользователя», издеваясь над телом моего метода Put HTTP с помощью Postman, и ЭТО РАБОТАЕТ:

 {
    "name":"Moe",
    "id":"1234"
}
 

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

Если вы хотите увидеть всю мою программу, пожалуйста!:

 package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

var (
    stringCatchedFromBodyJSON    string
    IDString         string
    storageConvertedToBytes []byte
    err                     error

    msg Message

    database Database
    storage  []Database
)

// Message is were body.json of method POST will be located.
type Message struct {
    NAME string `json:"name"`
    ID   string `json:"id"`
}

// Database is an example of a database
type Database struct {
    USER     string `json:"user"`
    PASSWORD string `json:"password"`
}

// You can add or remove manually this lines of code in order to edit the slice.
func arrayList() {
    storage = append(storage, Database{USER: "Max", PASSWORD: "1234"})
    storage = append(storage, Database{USER: "Rob", PASSWORD: "5678"})
    storage = append(storage, Database{USER: "Lee", PASSWORD: "9101"})
    storage = append(storage, Database{USER: "Joe", PASSWORD: "1213"})
    storage = append(storage, Database{USER: "May", PASSWORD: "1415"})
}

func put(w http.ResponseWriter, r *http.Request) {
    if r.Method == "PUT" {
        _, err = json.Marshal(storage)
        arrayList()

        // Read body.
        b, err := ioutil.ReadAll(r.Body)
        defer r.Body.Close()
        if err != nil {
            http.Error(w, err.Error(), 500)
            return
        }

        // Unmarshal.
        err = json.Unmarshal(b, amp;msg)
        if err != nil {
            http.Error(w, err.Error(), 500)
            return
        }

        stringCatchedFromBodyJSON = msg.NAME
        IDString = msg.ID

        if stringCatchedFromBodyJSON != database.USER {
            storage = append(storage, Database{USER: stringCatchedFromBodyJSON, PASSWORD: IDString})
            storageConvertedToBytes, _ = json.Marshal(storage)
            w.Header().Set("content-type", "application/json")
            w.Write(storageConvertedToBytes)
        } else {
            w.Header().Set("content-type", "application/json")
            w.Write([]byte("User already exist"))
        }

    } else {
        w.Header().Set("content-type", "application/json")
        w.Write([]byte("Wrong http method"))
    }
}

func main() {
    PORT := ":8000"
    http.HandleFunc("/put", put)
    log.Println("Starting server on address", PORT)
    err := http.ListenAndServe(PORT, nil)
    if err != nil {
        fmt.Println(err)
        panic(err)
    }
}
 

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

1. Не используйте отражение для такой задачи. Напишите обычную функцию.

2. Функция itemExists явно паникует, когда аргумент не является массивом. Вы намеревались проверить наличие среза: if arr.Kind() != reflect.Slice { panic("Invalid data-type") }

3. Мне удалось сделать это с помощью функции FOR, я создал функцию для сравнения моей переменной со всеми пользователями, представленными в моем срезе, и если моя переменная не равна никаким пользователям, добавьте мою переменную с ее идентификатором в срез.

Ответ №1:

Функция, которую я реализовал для решения этой проблемы, была:

 func searchForName() bool {
    for i := range storage {
        if storage[i].USER == stringCatchedFromBodyJSON {
            return true
        }
    }
    return false
}
 

Я реализовал эту функцию внутри оператора if:

 stringCatchedFromBodyJSON = msg.NAME
IDString = msg.ID
if searchForName() == false {
    storage = append(storage, Database{USER: stringCatchedFromBodyJSON, PASSWORD: IDString})
    storageConvertedToBytes, _ = json.Marshal(storage)
    w.Header().Set("content-type", "application/json")
    w.Write(storageConvertedToBytes)
} else {
    w.Header().Set("content-type", "application/json")
    w.Write([]byte("User already exist"))
}
 

Вот как я решаю свою проблему.