英文:
json decode key types
问题
我想从一个(静态模式)json文件中解码一组大数据。该文件仅包含数字数据,键都是整数。我知道如何将此json解码为包含map[string]int
或map[string]float32
字段的结构体,但我对字符串键不感兴趣,我需要将它们转换为整数。
所以我想知道的是:
- 有没有一种方法可以实现这一点,即直接从解码中获得一个包含
map[int]float32
类型字段的结构体, - 否则,如何在解码后以内存高效的方式实现这一点?
谢谢。
英文:
I want to decode a big set of data from a (static-schema) json file. The file contains exclusively numeric data, and keys are all integers. I know how to decode this json into a struct containing fields of map[string]int
or map[string]float32
using json.Unmarshal. But I have no interest in string keys, I'd need to convert them to int somehow.
So what I'd like to know is:
- Is there a way to achieve this, .ie getting a struct containing fields of map[int]float32 type directly from decoding,
- Otherwise how to achieve this after decoding, in a memory efficient manner ?
Thanks
答案1
得分: 6
JSON格式只指定了具有字符串键的键值对象。因此,encoding/json
包也只支持字符串键。
json/encoding
文档中指出:
>bool,用于JSON布尔值
float64,用于JSON数字
string,用于JSON字符串
[]interface{},用于JSON数组
map[string]interface{},用于JSON对象
nil,用于JSON null
如果你想使用encoding/json
包并将其转换为map[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 {
// 非整数键
}
}
fmt.Printf("%#v\n", b)
}
英文:
The JSON format only specifies key/value objects with string keys. Because of this, the encoding/json
package only supports string keys as well.
The json/encoding
documentation states:
>bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
If you want to use encoding/json
package and move it over to a map[int]float64, you can do the following (works with float32 as well):
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)
}
答案2
得分: 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 IntToFloat")
}
// 在这里进行魔法操作。
return nil
}
编辑
注意:http://golang.org/src/pkg/encoding/json/decode.go?s=2221:2269#L53 是标准库中Unmarshal
方法的实现。
http://golang.org/pkg/encoding/json/#Unmarshaler 是上述接口的来源。
英文:
The encoding/json
package includes an interface Unmarshaler
which has a single method: UnmarshalJSON(data []byte) error
.
If you're feeling brave you could implement that for the following:
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
Note: http://golang.org/src/pkg/encoding/json/decode.go?s=2221:2269#L53 is where the std library version of Unmarshal comes from.
http://golang.org/pkg/encoding/json/#Unmarshaler is where the interface referenced above comes from.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论