JSON解码键类型

huangapple go评论84阅读模式
英文:

json decode key types

问题

我想从一个(静态模式)json文件中解码一组大数据。该文件仅包含数字数据,键都是整数。我知道如何将此json解码为包含map[string]intmap[string]float32字段的结构体,但我对字符串键不感兴趣,我需要将它们转换为整数。

所以我想知道的是:

  1. 有没有一种方法可以实现这一点,即直接从解码中获得一个包含map[int]float32类型字段的结构体,
  2. 否则,如何在解码后以内存高效的方式实现这一点?

谢谢。

英文:

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:

  1. Is there a way to achieve this, .ie getting a struct containing fields of map[int]float32 type directly from decoding,
  2. 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)
}

Playground

英文:

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

Playground

答案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.

huangapple
  • 本文由 发表于 2013年8月28日 20:55:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/18488563.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定