反转Golang中<value,key>格式的地图

I have a map for my program that looks like following:

fruit_map := map[string]string {
    "apple": "likey",
    "orange": "no likey",
}

I would like to reverse it so that it reads the following:

{
    "likey": "apple",
    "no likey": "orange",
}

There are no duplicates in values. Also, my map is small - about 200 keys. I did not find any built-in method to reverse a map like this. Is there any way to do this fast? I am not much bothered about space complexity, but the solution needs to be fast.

Thanks.

You may write a for loop to iterate over the key-value pair of original map, and put them in a new map (see function reverseMap)

Code@http://play.golang.org/p/mCFmRT8nzP

package main

import (
    "fmt"
)

func main() {
    fruit_map := map[string]string{
        "apple":  "likey",
        "orange": "no likey",
    }

    reversedMap := reverseMap(fruit_map)
    fmt.Println(reversedMap)
}

func reverseMap(m map[string]string) map[string]string {
    n := make(map[string]string)
    for k, v := range m {
        n[v] = k
    }
    return n
}

Output:

map[likey:apple no likey:orange]

BTW, it is not idiomatic to name go variable like fruit_map, you really should use camel-case, like fruitMap.

You are right, there is nothing built-in to accomplish this but it is really straightforward:

package main

import "fmt"

func main() {

    fruit_map := map[string]string{
        "apple":  "likey",
        "orange": "no likey",
    }

    //create your new empty map that will hold your reversed contents.
    reversed_fruit_map := make(map[string]string)

    for k, v := range fruit_map{
        reversed_fruit_map[v] = k
    }

    fmt.Println(reversed_fruit_map)
}

This outputs the following:

map[likey:apple no likey:orange]

Check it out on the playground. If this is common you can always extract out into your own function.

There isn't a built in function to do that, but it's simple enough with a for loop.

fruit_map := map[string]string {
    "apple": "likey",
    "orange": "no likey",
}

reversed_map := make(map[string]string)

for key,value := range fruit_map {
    reversed_map[value] = key
}

see: http://play.golang.org/p/BQjqUsf9aU

The other answers offer the simple solution based on handling the map directly.

An alternative solution is to encapsulate a bidirectional map as a self-contained utility, which has the advantage that you could write thorough unit tests for it and then be able to rely on it to operate correctly via a simple API.

Here's my example implementation (which is incomplete and doesn't yet have the necessary unit tests):

package main

import (
    "fmt"
)

func main() {
    biMap := NewBiMap()
    biMap.Put("apple", "likey")
    biMap.Put("orange", "no likey")
    v, _ := biMap.GetByValue("no likey")
    fmt.Println(v)
}

type BiMap struct {
    ab map[string]string
    ba map[string]string
}

func NewBiMap() *BiMap {
    return &BiMap{make(map[string]string), make(map[string]string)}
}

func (m *BiMap) Put(key, value string) *BiMap {
    m.ab[key] = value
    m.ba[value] = key
    return m
}

func (m *BiMap) GetByKey(key string) (value string, exists bool) {
    value, exists = m.ab[key]
    return
}

func (m *BiMap) GetByValue(value string) (key string, exists bool) {
    key, exists = m.ba[value]
    return
}

func (m *BiMap) Len() int {
    return len(m.ab)
}

func (m *BiMap) DeleteKey(key string) *BiMap {
    value, exists := m.ab[key]
    if exists {
        delete(m.ab, key)
        delete(m.ba, value)
    }
    return m
}

func (m *BiMap) DeleteValue(value string) *BiMap {
    key, exists := m.ba[value]
    if exists {
        delete(m.ab, key)
        delete(m.ba, value)
    }
    return m
}