using go, how do i turn a map[int]T to a map[string]T to use with JSON?

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

using go, how do i turn a map[int]T to a map[string]T to use with JSON?

问题

我的代码中充斥着像下面这样的函数:

func TransformMapClassA(mapOfIntToClassA map[int]*ClassA) map[string]*ClassA {
  mapOfStringToClassA := make(map[string]*ClassA)
  for id, obj := range mapOfIntToClassA {
    mapOfStringToClassA[fmt.Sprintf("%d", obj.Id)] = obj
  }
  return mapOfStringToClassA
}

每个类在我的应用程序中都有一个类似的函数。我这样做是为了能够对现有的映射进行json.Marshal。有没有一种通用的方法可以做到这一点,这样我就不必为每个类编写一个函数了?我尝试过像这样做:

type Int64JSON int64 `json:",string"`

并在我的原始映射中使用Int64JSON,但编译器不喜欢类型定义中的json标签 using go, how do i turn a map[int]T to a map[string]T to use with JSON?

非常感谢!

英文:

My code is getting plastered with functions like the following:

func TransformMapClassA(mapOfIntToClassA map[int]*ClassA) map[string]*ClassA {
  mapOfStringToClassA := make(map[string]*ClassA)
  for id, obj := range mapOfIntToClassA {
    mapOfStringToClassA[fmt.Sprintf("%d" obj.Id)] = obj
  }
  return mapOfStringToClassA
}

written once for each class in my application. I'm doing this, so I can json.Marshal the existing map. Is there a generic way of doing this, so I don't have to write one function per class? I've tried doing things like:

type Int64JSON int64 `json:",string"`

and using Int64JSON in my original maps, but the compiler doesn't like the json tag in a type definition using go, how do i turn a map[int]T to a map[string]T to use with JSON?

Many thanks in advance!

答案1

得分: 2

如果你仍然想使用反射来创建一个从任何类型的映射返回map[string]interface{}的函数,你可以按照以下步骤进行操作:

func TransformMap(m interface{}) (map[string]interface{}, error) {

	v := reflect.ValueOf(m)

	if v.Kind() != reflect.Map {
		return nil, errors.New("需要映射类型")
	}

	result := make(map[string]interface{}, v.Len())

	keys := v.MapKeys()
	for _, k := range keys {
		result[fmt.Sprint(k.Interface())] = v.MapIndex(k).Interface()
	}

	return result, nil
}

Playground

英文:

If you still want to use reflection to create a function that returns a map[string]interface{} from any type of map, you can do the following:

func TransformMap(m interface{}) (map[string]interface{}, error) {

	v := reflect.ValueOf(m)

	if v.Kind() != reflect.Map {
		return nil, errors.New("Map required")
	}

	result := make(map[string]interface{}, v.Len())

	keys := v.MapKeys()
	for _, k := range keys {
		result[fmt.Sprint(k.Interface())] = v.MapIndex(k).Interface()
	}

	return result, nil
}

Playground

答案2

得分: 1

有几种方法可以实现这个目标。其中一种方法是使用通用的map[interface{}]interface{},并编写一个转换函数,如下所示:

func stringMap(m map[interface{}]interface{}) map[string]interface{} {
    result := make(map[string]interface{})
    for k, v := range m {
        result[fmt.Sprint(k)] = v
    }
    return result
}

(在 play 上)

你也可以使用反射等方法。

话虽如此,在执行任何操作之前,我建议你考虑一下是否真的需要这样做。使用正确的类型有几个好处(类型检查、读取时无需断言、性能、内存使用等),而且需要编写的代码量相对较小。

英文:

There are a number of ways you can do that. One of them is using a generic map[interface{}]interface{}, and having a conversion function such as:

func stringMap(m map[interface{}]interface{}) map[string]interface{} {
	result := make(map[string]interface{})
	for k, v := range m {
		result[fmt.Sprint(k)] = v
	}
	return result	
}

(on play)

You might also use reflection, etc.

That said, before doing any of that, I'd ponder whether it's really so much burden to do that for the real types. There are several benefits in having proper typing (type checking, no need for assertions when reading, performance, memory use, etc), and it's a fairly small amount of code.

huangapple
  • 本文由 发表于 2013年9月24日 23:51:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/18986396.html
匿名

发表评论

匿名网友

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

确定