Search code examples
gomapping

How to write a bidirectional mapping in Go?


I am writing a simple console game and would like to map a player to a symbol. With two players my approach looks like this:

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

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

Of cause you could also write this as two maps mapping int to string and string to int. Both the above approach and the map approach seem error-prone. Is there a more idiomatic way to write this in go? Maybe some non-iota enum way?


Solution

  • [I assume your example is just minimal and that your actual mapping has more than two options. I also assume you meant bi-directonal mapping]

    I would write one map:

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

    And then would create a function to populate a different map string2player programmatically. Something like this:

    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