Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse a map in <value, key> format in Golang

Tags:

go

map

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.

like image 679
jyotiska Avatar asked Apr 21 '14 03:04

jyotiska


2 Answers

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@https://play.golang.org/p/5y1gABTpdb8

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, len(m))
    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.

like image 97
Mingyu Avatar answered Oct 19 '22 02:10

Mingyu


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
}
like image 4
Rick-777 Avatar answered Oct 19 '22 01:10

Rick-777