2014-04-21 13 views
5

Mam mapę dla mojego programu, który wygląda jak następuje:Rewers mapy w formacie <value, key> w Golang

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

chciałbym go odwrócić tak, że czyta, co następuje:

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

Nie ma duplikatów w wartościach. Ponadto moja mapa jest mała - około 200 kluczy. Nie znalazłem żadnej wbudowanej metody odwrócenia takiej mapy. Czy jest jakiś sposób, aby to zrobić szybko? Nie zawracam sobie głowy złożonością przestrzeni, ale rozwiązanie musi być szybkie.

Dzięki.

Odpowiedz

2

Możesz napisać for pętli do iteracyjne nad parę klucz-wartość oryginalnej mapy, i umieścić je w nowej mapy (patrz funkcja reverseMap)

kod @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 
} 

wyjściowa:

map[likey:apple no likey:orange] 

Przy okazji, nie jest idiomatyczne nazywanie zmiennej zmiennej jak fruit_map, naprawdę powinieneś używać wielbłąda, jak fruitMap.

+0

Skoro można oczekiwać rozmiar mapie 'm' być identyczne z rozmiar mapy 'm' (przy założeniu braku duplikatów wartości), możesz użyć:' n: = make (map [string] string, len (m)) ', aby zaoszczędzić wystarczająco dużo miejsca i uniknąć ponownego przydziału w pętli. – dubek

0

Masz rację, nie ma nic wbudowanej do osiągnięcia tego celu, ale to jest naprawdę prosta:

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) 
} 

ten wyprowadza następujące:

map[likey:apple no likey:orange] 

Sprawdź to na playground. Jeśli jest to powszechne, zawsze możesz wydobyć z nich swoją własną funkcję.

0

Nie ma wbudowanej funkcji do tego, ale jest dość prosta z pętlą for.

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 
} 

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

3

Pozostałe odpowiedzi oferują proste rozwiązanie oparte na obsłudze mapy bezpośrednio.

Alternatywnym rozwiązaniem jest hermetyzacja mapy dwukierunkowej jako samodzielnego narzędzia, która ma tę zaletę, że można napisać dla niej dokładne testy jednostkowe, a następnie móc polegać na tym, aby działała poprawnie za pomocą prostego interfejsu API.

Oto my example implementatio n (co jest niekompletny i nie ma jeszcze niezbędne testy jednostkowe):

pakiet główny

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 
} 
Powiązane problemy