从 Go 中的数组/切片中获取元素的索引或从映射中获取值的键?

onl*_*ing 6 go

我有一个枚举的字符串列表(它们是常量,例如国家列表),我希望能够在提供枚举的 int 值时获取该字符串,反之亦然,能够获取枚举的 int 值提供字符串时。这是为了在两者之间进行数据库事务的转换。

var MyData = [...]string {
  "string1", // index 0
  "string2", // index 1
  "string3", // index 2  
}
Run Code Online (Sandbox Code Playgroud)

对于像 python 这样的语言来说,这很容易,只需执行 MyData[1] 即可获取“string2”,MyData.index(“string2”) 即可获取 1。

一些可能的解决方案是

  • 编写我自己的函数通过迭代数组/切片来获取索引
  • 对数组/切片进行排序并使用搜索函数返回索引(尽管这不允许未排序的序列,这是我更喜欢的)
  • 维护一个互相镜像的映射和数组,这很容易出错。

说到映射,我们可以访问特定值的键吗?然后我可以简单地拥有一个如下所示的映射,并且能够在提供 int 值时获取字符串键。

var MyData = map[string]int {
  "string1": 0,
  "string2": 1,
  "string3": 2,
}
Run Code Online (Sandbox Code Playgroud)

更新:在我接受我的答案之前,我想更彻底地解释这个问题,我知道这一定是相当普遍的。我基本上有一组恒定的字符串(例如国家列表),每个字符串都有一个关联的整数值。在我的数据库中,我只是存储整数以节省空间,因为有数百万个条目。但是,当我显示数据库中的条目时,我需要显示字符串值,以便用户可读。一个简单的数组就可以做到这一点。但是,我还需要向数据库添加条目(例如新人员及其居住国家/地区),在这种情况下,需要将从表单中输入的国家/地区字符串转换为该整数值。同样,这只是一个示例用例,但目标保持不变。我需要一个可以在字符串值和枚举 int 值之间双向转换的表。最明显的事情是维护一个数组(用于 int 到 string 的转换)和一个映射(用于 string 到 int 的转换)。我不想手动维护这两个变量,因为这很容易出错。因此,我下面的解决方案是仅维护一个数组,并让构造函数方法在程序首次运行时在运行时自动构建地图。这样做的优点是,当我根据字符串获取整数值时,不需要迭代整个数组(这是另一个建议的解决方案)。

onl*_*ing 3

这是我之前提到的一个解决方案,它非常适合静态切片(这是我的用例)。每次我想要一个值的索引时迭代切片会增加不必要的延迟,特别是因为我的数据在运行时是静态的。这只是创建一个结构体,该结构体初始化切片并创建相应的逆映射。然后我将使用 GetKey 和 GetVal 方法通过提供 int 'value' 来获取字符串 'key',或者通过提供字符串 'key' 来获取 int 'value'。也许 Go 中已经有一种方法可以获取映射的特定值的键。

type MyData struct {
    dataslice []string
    datamap map[string]int
}

func NewMyData() *MyData {
    m := new(MyData)
    m.dataslice= []string {
        "string1",
        "string2",
        "string3",
    }
    m.datamap = make(map[string]int)
    for x := range m.dataslice {
        m.datamap[m.dataslice[x]] = x
    }
    return m
}

func (m *MyData) GetKey(x int) string {
    return m.dataslice[x]
}

func (m *MyData) GetVal(x string) int {
    return m.datamap[x]
}
Run Code Online (Sandbox Code Playgroud)