Existe-t-il un moyen simple dans Go de vérifier si le JSON donné est un objet {}
ou un tableau []
?
La première chose qui me vient à l'esprit est de json.Unmarshal ()
dans une interface, puis de voir si cela devient une carte, ou une tranche de cartes. Mais cela semble assez inefficace.
Puis-je simplement vérifier si le premier octet est un {
ou un [
? Ou y a-t-il une meilleure façon de faire cela qui existe déjà?
3 Réponses :
Utilisez ce qui suit pour détecter si le texte JSON dans la [] byte
value data
est un tableau ou un objet:
// Get slice of data with optional leading whitespace removed. // See RFC 7159, Section 2 for the definition of JSON whitespace. x := bytes.TrimLeft(data, " \t\r\n") isArray := len(x) > 0 && x[0] == '[' isObject := len(x) > 0 && x[0] == '{'
isArray et isObject
sont tous deux évalués à faux. Les valeurs isArray
et isObject
peuvent également être évaluées à false lorsque le JSON n'est pas valide.
Juste ce que je cherchais, merci. Je ne devrais pas avoir à m'inquiéter du fait que la valeur de niveau supérieur soit autre chose dans mon cas d'utilisation, car elles seraient toutes invalides de toute façon.
Utilisez un commutateur de type pour déterminer le type. Ceci est similaire à la réponse de Xay, mais plus simple:
var v interface{} if err := json.Unmarshal(data, &v); err != nil { // handle error } switch v := v.(type) { case []interface{}: // it's an array case map[string]interface{}: // it's an object default: // it's something else }
Je pense que c'est la meilleure réponse puisque le json est validé et c'est simple et concis.
C'est très inefficace.
C'est ce que j'ai pensé faire en premier, mais c'est certainement moins efficace, surtout compte tenu de l'utilisation de la réflexion à l'intérieur de Unmarshal
.
@ robbieperry22 C'est inefficace, mais Unmarshal n'utilise pas la réflexion lors de la suppression de l'appel à interface {}
.
Analysez pas à pas votre JSON en utilisant json.Decoder
. Cela a l'avantage sur les autres réponses de:
Remarque, ce code n'est pas testé, mais devrait suffire à vous donner une idée. Il peut également être facilement développé pour rechercher des nombres, des booléens ou des chaînes, si vous le souhaitez.
t, err := jsonType(bytes.NewReader(myValue))
Notez que cela a consommé les premiers octets de dans
. C'est un exercice pour le lecteur de faire une copie, si nécessaire. Si vous essayez de lire à partir d'une tranche d'octets ( [] octet
), convertissez-la d'abord en lecteur:
type jsonType(in io.Reader) (string, error) { dec := json.NewDecoder(in) // Get just the first valid JSON token from input t, err := dec.Token() if err != nil { return "", err } if d, ok := t.(json.Delim); ok { // The first token is a delimiter, so this is an array or an object switch (d) { case "[": return "array", nil case "{": return "object", nil default: // ] or } return nil, errors.New("Unexpected delimiter") } } return nil, errors.New("Input does not represent a JSON object or array") }