2014-04-21 14 views
5

Tôi có một bản đồ cho chương trình của tôi trông giống như sau:Đảo ngược bản đồ ở định dạng <value, key> trong Golang

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

tôi muốn đảo ngược nó để nó đọc như sau:

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

Không có bản sao nào trong các giá trị. Ngoài ra, bản đồ của tôi là nhỏ - khoảng 200 phím. Tôi không tìm thấy bất kỳ phương pháp tích hợp nào để đảo ngược bản đồ như thế này. Có cách nào để làm điều này nhanh không? Tôi không bận tâm về độ phức tạp của không gian, nhưng giải pháp cần phải nhanh chóng.

Cảm ơn.

Trả lời

2

Bạn có thể viết một vòng lặp for để lặp qua các cặp khóa-giá trị của bản đồ gốc, và đặt chúng trong một bản đồ mới (xem chức năng reverseMap)

Mã @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, nó không phải là thành ngữ với tên biến đi như fruit_map, bạn thực sự nên sử dụng trường hợp lạc đà, như fruitMap.

+0

Vì bạn hy vọng quy mô của bản đồ 'm' để được giống hệt nhau đến kích thước của bản đồ 'm' (giả định không có giá trị trùng lặp), bạn có thể muốn sử dụng:' n: = make (ánh xạ chuỗi ký tự, len (m)) 'để tiết kiệm đủ không gian và tránh tái phân bổ trong vòng lặp. – dubek

0

Bạn là đúng, không có gì là tích hợp để thực hiện điều này nhưng nó thực sự là đơn giản:

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

này kết quả đầu ra như sau:

map[likey:apple no likey:orange] 

Check it out trên playground. Nếu điều này là phổ biến, bạn luôn có thể tách ra thành chức năng của riêng bạn.

0

Không có chức năng tích hợp để thực hiện điều đó, nhưng nó đủ đơn giản với vòng lặp 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 
} 

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

3

Các câu trả lời khác cung cấp giải pháp đơn giản dựa trên việc xử lý bản đồ trực tiếp.

Giải pháp thay thế là gói gọn bản đồ hai chiều như một tiện ích độc lập, có lợi thế là bạn có thể viết các bài kiểm tra đơn vị kỹ lưỡng cho nó và sau đó có thể dựa vào nó để vận hành chính xác thông qua API đơn giản.

Dưới đây là my example implementatio n (đó là chưa đầy đủ và chưa có đơn vị xét nghiệm cần thiết):

gói chính

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 
}