2014-04-21 9 views
5

ho una mappa per il mio programma che si presenta come segue:Reverse una mappa in formato <value, key> in Golang

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

vorrei invertire in modo che esso legge la seguente:

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

Non ci sono duplicati nei valori. Inoltre, la mia mappa è piccola - circa 200 chiavi. Non ho trovato alcun metodo integrato per invertire una mappa come questa. C'è un modo per farlo in fretta? Non mi preoccupo molto della complessità dello spazio, ma la soluzione deve essere veloce.

Grazie.

risposta

2

Si può scrivere un ciclo for per scorrere la coppia chiave-valore della mappa originale, e metterli in una nuova mappa (vedi funzione reverseMap)

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

uscita:

map[likey:apple no likey:orange] 

BTW, non è univoco nominare go variabile come fruit_map, si dovrebbe davvero usare il caso cammello, come fruitMap.

+0

Dal momento che si prevede che la dimensione della mappa 'M' per essere identico al dimensione della mappa 'm' (supponendo che non ci siano valori duplicati), potresti voler usare:' n: = make (map [stringa] string, len (m)) 'per risparmiare spazio ed evitare riallocazioni durante il ciclo. – dubek

0

Hai ragione, non c'è nulla di built-in per raggiungere questo obiettivo, ma è davvero semplice:

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

Emette il seguente:

map[likey:apple no likey:orange] 

Check it out sul playground. Se questo è comune, puoi sempre estrarre la tua funzione.

0

Non c'è una funzione incorporata per farlo, ma è abbastanza semplice con un ciclo 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 
} 

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

3

Le altre risposte offrono la soluzione semplice basata sulla gestione diretta della mappa.

Una soluzione alternativa consiste nell'incapsulare una mappa bidirezionale come un'utilità indipendente, che presenta il vantaggio che è possibile scrivere test unitari completi per esso e quindi essere in grado di fare affidamento su di esso per funzionare correttamente tramite una semplice API.

Ecco my example implementatio n (che è incompleto e non dispone ancora i test di unità necessarie):

pacchetto principale

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 
} 
Problemi correlati