go: How to json.Marshal map[int]int?

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

go: How to json.Marshal map[int]int?

问题

我知道,JSON只支持字符串作为键,不支持其他类型。

但是,将整个map[int]int转换为临时的map[string]int并不总是可行的,因为后者可能无法适应内存。

有没有一种方法可以在运行时将整数键转换为其他类型?是否有任何类似JSON的格式支持整数键?比如YAML?或者一些二进制格式?

英文:

I know, Json does not support anything else than strings for keys.

But converting entire map[int]int to temporaty map[string]int is not always possible because second one does not fit into memory.

Is there an approach to convert int key on the fly?

Is there any json-like format with int keys? YAML? Some binary format?

答案1

得分: 1

不,你不能即时转换地图。在填充新地图之前,你需要保留原始地图(然后可以删除它)。

首先,你需要问自己一个问题:你打算如何使用这个 JSON 数据,因为现代计算机有很多内存,所以即使存储 4GB 的数据也不是问题(而且我很怀疑你会发送 4GB 的 JSON 请求)。

一旦你知道为什么要对数据进行编码,你就可以寻找合适的格式。

例如,你可以序列化你的地图。

package main

import (
	"fmt"
	"encoding/gob"
	"bytes"
)

var m = map[int]string{1: "one", 2: "two", 3: "three"}

func main() {
	buf := new(bytes.Buffer)
	encoder := gob.NewEncoder(buf)

	err := encoder.Encode(m)
	if err != nil {
		panic(err)
	}

	// 你的编码数据
	fmt.Println(buf.Bytes())

	var decodedMap map[int]string
	decoder := gob.NewDecoder(buf)

	err = decoder.Decode(&decodedMap)
	if err != nil {
		panic(err)
	}

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

Go Playground

英文:

No, you can't convert the map on the fly. You will need to have your original map till you populate the new one (then it can be removed).

First question you have to ask yourself: what are you going to do with that json, because modern computers have a lot of RAM, so storing even 4gb will not be a problem (and I highly doubt you are going to send 4gb json request).

Once you know why exactly are you encoding your stuff you can look for an appropriate format.

For example you can serialize your map.

<kbd>Go Playground</kbd>

package main

import (
	&quot;fmt&quot;
	&quot;encoding/gob&quot;
	&quot;bytes&quot;
)

var m = map[int]string{1:&quot;one&quot;, 2: &quot;two&quot;, 3: &quot;three&quot;}

func main() {
	buf := new(bytes.Buffer)
	encoder := gob.NewEncoder(buf)
	
	err := encoder.Encode(m)
	if err != nil {
		panic(err)
	}

// your encoded stuff
fmt.Println(buf.Bytes())
	
	var decodedMap map[int]string
	decoder := gob.NewDecoder(buf)
	
	err = decoder.Decode(&amp;decodedMap)
	if err != nil {
		panic(err)
	}
	
	fmt.Printf(&quot;%#v\n&quot;, decodedMap)
}

答案2

得分: 0

在代码中进行编码。这很简单,而且可能会更快。

以下代码应该可以实现:

var buf bytes.Buffer
first := true
fmt.Fprint(&buf, "{")
for k, v := range m {
    if first {
        first = false
    } else {
        fmt.Fprint(&buf, ",")
    }
    fmt.Fprintf(&buf, `"%d":%d`, k, v)
}
fmt.Fprint(&buf, "}")

如果你需要将其传递给 `encoding/json`你可以使用 `json.RawMessage(buf.Bytes())`
英文:

Do the encoding in code. It's easy and will probably be faster as a bonus.

This should work:

var buf bytes.Buffer
first := true
fmt.Fprint(&amp;buf, &quot;{&quot;)
for k, v := range m {
	if first {
		first = false
	} else {
		fmt.Fprint(&amp;buf, &quot;,&quot;)
	}
	fmt.Fprintf(&amp;buf, `&quot;%d&quot;:%d`, k, v)
}
fmt.Fprint(&amp;buf, &quot;}&quot;)

If you need to pass this on to encoding/json you can use json.RawMessage(buf.Bytes()).

huangapple
  • 本文由 发表于 2015年11月28日 05:47:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/33965169.html
匿名

发表评论

匿名网友

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

确定