如何在Go中编写双向Map?

yv5phkfx  于 2023-04-27  发布在  Go
关注(0)|答案(4)|浏览(212)

我正在编写一个简单的控制台游戏,并希望将一个玩家Map到一个符号。对于两个玩家,我的方法如下所示:

func playerToString(p player) string {
    if p == 0 {
        return "X"
    }
    return "O"
}

func stringToPlayer(s string) player {
    if s == "X" {
        return 0
    }
    return 1
}

当然,你也可以把它写成两个Map,一个是int到string,另一个是string到int。上面的方法和map方法看起来都容易出错。在go中有没有更习惯的方法来写这个?也许是一些非iota枚举的方法?

but5z9lq

but5z9lq1#

  • [我假设你的例子只是最小的,你的实际Map有两个以上的选项。我还假设你的意思是双向Map]*

我会写一张Map:

var player2string = map[int]string{
  0: "0",
  1: "X",
  // etc...
}

然后会创建一个函数来以编程方式填充一个不同的map string2player。类似于以下内容:

var player2string = map[int]string{
    0: "0",
    1: "X",
    // etc...
}

var string2player map[string]int = convertMap(player2string)

func convertMap(m map[int]string) map[string]int {
    inv := make(map[string]int)
    for k, v := range m {
        inv[v] = k
    }
    return inv

}

func main() {
    fmt.Println(player2string)
    fmt.Println(string2player)
}

Try it on the Go playground

xu3bshqb

xu3bshqb2#

除了Eli的答案,你还可以做另外两个改变。你可以把to-symbol函数变成一个player类型的方法。因为玩家的值是整数(从零开始连续),你可以用一个切片而不是一个Map来存储int-to-symbolMap--这样存储和查找起来更有效。

type player int

var playerSymbols = []string{"X", "O", "A", "B", "C", "D", "E", "F", "G", "H"}

func (p player) Symbol() string {
    if int(p) < 0 || int(p) >= len(playerSymbols) {
        return "?" // or panic?
    }
    return playerSymbols[p]
}

这个方法签名甚至可以是String() string,所以它是一个fmt.Stringer,这对于打印和调试很有用。

a0zr77ik

a0zr77ik3#

假设你不需要任何特定的Map,玩家整数值的序列为0,1,2,3,...,25,你可以直接生成玩家符号,而不需要使用Map,如下面的片段所示:

type player int

func ToSymbol(p player) string {
    return fmt.Sprintf("%c", 'A' + p)
}

func ToPlayer(symbol string) player {
    return player([]rune(symbol)[0] - 'A')
}
cngwdvgl

cngwdvgl4#

对于任何人,发现这个线程下来,我想一个更符合人体工程学的解决方案,双向值Map,所以我创建了一个小模块来做到这一点。如果有人正在寻找一个现成的解决方案。
https://github.com/graytonio/go-bidirectional-map

myMap := bidmap.NewMap(map[string]int{
    "foo": 3,
    "bar": 4,
})

fmt.Println(myMap.GetP("foo"))
// Output: 3 true

fmt.Println(myMap.GetS(3))
// Output: foo true

编辑:添加了示例代码

相关问题