6
votes

Vérifiez si JSON est un objet ou un tableau

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à?


0 commentaires

3 Réponses :


9
votes

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.


1 commentaires

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.



3
votes

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
}


4 commentaires

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 {} .



4
votes

Analysez pas à pas votre JSON en utilisant json.Decoder . Cela a l'avantage sur les autres réponses de:

  1. Être plus efficace que de décoder la valeur entière
  2. Utilisation des règles d'analyse JSON officielles et génération d'erreurs standard si vous obtenez une entrée non valide.

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")
}


0 commentaires