Одним из советов было бы избежать использования ключевых слов или функций в качестве имен переменных. В вашем коде выше вы используете список как переменную:
list = [1, 2, 3]
Я бы посоветовал использовать list
в качестве имени переменной, поскольку list на самом деле уже определен как встроенный тип. Как заметил ChaseTheSun и squiguy, там не так много, а затем
l = [1, 2, 3]
l.append(4)
print l ## [1, 2, 3, 4]
Тот, который, вероятно, будет работать хорошо, это просто декодировать, перекодировать, а затем проверять длину нового json на старый json:
https://play.golang.org/ p / 50P-x1fxCzp
package main
import (
"encoding/json"
"fmt"
)
func main() {
jsn := []byte("{\"a\": \"b\", \"a\":true,\"c\":[\"field_3 string 1\",\"field3 string2\"]}")
var m map[string]interface{}
err := json.Unmarshal(jsn, &m)
if err != nil {
panic(err)
}
l := len(jsn)
jsn, err = json.Marshal(m)
if err != nil {
panic(err)
}
if l != len(jsn) {
panic(fmt.Sprintf("%s: %d (%d)", "duplicate key", l, len(jsn)))
}
}
Правильный способ сделать это состоял бы в том, чтобы повторно реализовать функцию json.Decode
и сохранить карту найденных ключей, но вышеуказанное должно работать (особенно если вы сначала разделили все пробелы из json, используя jsn = bytes.Replace(jsn, []byte(" "), []byte(""), -1)
, чтобы защитить от ложных срабатываний.
Используйте json.Decoder , чтобы пройти через JSON.
func check(d *json.Decoder, path []string) error {
// Get next token from JSON
t, err := d.Token()
if err != nil {
return err
}
delim, ok := t.(json.Delim)
// There's nothing to do for simple values (strings, numbers, bool, nil)
if !ok {
return nil
}
switch delim {
case '{':
keys := make(map[string]bool)
for d.More() {
// Get field key
t, err := d.Token()
if err != nil {
return err
}
key := t.(string)
// Check for duplicates
if keys[key] {
fmt.Printf("Duplicate %s\n", strings.Join(append(path, key), "/"))
}
keys[key] = true
// Check value
if err := check(d, append(path, key)); err != nil {
return err
}
}
// Consume trailing }
if _, err := d.Token(); err != nil {
return err
}
case '[':
i := 0
for d.More() {
if err := check(d, append(path, strconv.Itoa(i))); err != nil {
return err
}
i++
}
// Consume trailing ]
if _, err := d.Token(); err != nil {
return err
}
}
return nil
}
Вот как это можно назвать:
data := `{"a": "b", "a":true,"c":["field_3 string 1","field3 string2"], "d": {"e": 1, "e": 2}}`
if err := check(json.NewDecoder(strings.NewReader(data)), nil); err != nil {
log.Fatal(err)
}
Выход:
Duplicate a
Duplicate d/e
json.Compact
для удаления лишних пробелов – Slabgorb 30 April 2018 в 20:48