2013-08-28 3 views
0

Я хочу декодировать большой набор данных из json-файла (статической-схемы). Файл содержит исключительно числовые данные, а ключи - целые. Я знаю, как декодировать этот json в структуру, содержащую поля map[string]int или map[string]float32 с использованием json.Unmarshal. Но я не интересуюсь строковыми ключами, мне нужно каким-то образом преобразовать их в int.json decode key types

Так что я хотел бы знать:

  1. Есть ли способ для достижения этой цели, .ie получения структуры, содержащие поля карты [INT] float32 типа непосредственно от декодирования,
  2. В противном случае как добиться этого после декодирования в эффективном режиме памяти?

Благодаря

+0

Подсказка: запустите свой json-файл через http://jsonlint.com/, чтобы узнать, как он относится к вашему «json». – Crisfole

+1

'Результаты Действительно JSON.' Я когда-либо упоминал, что у меня была проблема с моим json-файлом? – ybycode

+0

Нет, но использование чисел как ключей в json-файле является недопустимым и приведет к тому, что большинство json-инструментов автоматически преобразуют их в строки. Возможно, вы сможете разблокировать пакет encoding/json и заставить его делать то, что вы хотите ... но в любом случае мой голос пошел на ответ @ ANisus (правильный) ниже – Crisfole

ответ

6

В JSON format определяет только объекты ключ/значение с строковыми ключами. Из-за этого пакет encoding/json поддерживает только строковые ключи.

В json/encoding документация говорится:

BOOL, для JSON булевых
float64, для чисел в формате JSON
строки, для JSON строки
[] интерфейс {}, для JSON массивов
карты [струнной ] интерфейс {}, для JSON объекты
ноля для JSON нулевого

Если вы хотите использовать encoding/json пакет и переместить его на карте [Int] float64, вы можете сделать следующее (работает с float32 а):

package main 

import (
    "fmt" 
    "strconv" 
) 

func main() { 
    a := map[string]float64{"1":1, "2":4, "3":9, "5":25} 
    b := make(map[int]float64, len(a)) 

    for k,v := range a { 
     if i, err := strconv.Atoi(k); err == nil { 
      b[i] = v 
     } else { 
      // A non integer key 
     } 
    } 

    fmt.Printf("%#v\n", b) 
} 

Playground

0

Пакет encoding/json включает в себя интерфейс Unmarshaler, который имеет один метод: UnmarshalJSON(data []byte) error.

Если вы чувствуете себя храбрыми вы могли осуществить это для следующих целей:

type IntToFloat map[int]float32 

func (itf *IntToFloat) UnmarshalJSON(data []byte) error { 
    if itf == nil { 
     return errors.New("Unmarshalling JSON for a null IntToFload") 
    } 
    // MAGIC Goes here. 
    return nil 
} 

EDIT

Примечания: http://golang.org/src/pkg/encoding/json/decode.go?s=2221:2269#L53 находится где станд версия библиотеки распаковать приходит.

http://golang.org/pkg/encoding/json/#Unmarshaler - это место, на которое ссылается вышеупомянутый интерфейс.

+1

Спасибо за этот ответ! Я не уверен, что я достаточно квалифицирован, чтобы идти прямо сейчас, чтобы использовать это решение, хотя ^^ – ybycode