Попытка поймать повторяющиеся атрибуты в JSON при unmarshalling в Go [duplicate]

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

list = [1, 2, 3]

Я бы посоветовал использовать list в качестве имени переменной, поскольку list на самом деле уже определен как встроенный тип. Как заметил ChaseTheSun и squiguy, там не так много, а затем

l = [1, 2, 3]
l.append(4)
print l  ## [1, 2, 3, 4]

2
задан Mike Aguilar 30 April 2018 в 20:28
поделиться

2 ответа

Тот, который, вероятно, будет работать хорошо, это просто декодировать, перекодировать, а затем проверять длину нового 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), чтобы защитить от ложных срабатываний.

1
ответ дан dave 15 August 2018 в 16:18
поделиться
  • 1
    вы, вероятно, можете использовать json.Compact для удаления лишних пробелов – Slabgorb 30 April 2018 в 20:48
  • 2
    Я думал, что ОП задал вопрос «как обнаружить дублирующий атрибут», а не «как обнаружить , если есть дублирующий атрибут», – Charles Shiller 30 April 2018 в 22:24

Используйте 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

Запустите его на игровой площадке

6
ответ дан ThunderCat 15 August 2018 в 16:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: