2012-11-16 34 views
47

如果我有一張地圖,m是越來越有價值觀的片更好的辦法V,那麼在golang中,從地圖獲取一部分值有很好的方法嗎?

package main 
import (
    "fmt" 
) 

func main() { 
    m := make(map[int]string) 

    m[1] = "a" 
    m[2] = "b" 
    m[3] = "c" 
    m[4] = "d" 

    // Can this be done better? 
    v := make([]string, len(m), len(m)) 
    idx := 0 
    for _, value := range m { 
     v[idx] = value 
     idx++ 
    } 

    fmt.Println(v) 
} 

是否有地圖的內置功能? Go包中是否有函數,或者如果需要,這是最好的代碼嗎?

+0

,而不是「_」在你的for循環,IDX稱它爲和溝IDX +業務 –

+0

不,他不能,當你在範圍內的地圖,它返回鍵,值不是指數值。在他的例子中,他使用1作爲第一個鍵,並且會使分片v中的索引不正確,因爲開始索引將是1而不是0,並且當它到達4時它將超出範圍。 https://play.golang.org/p/X8_SbgxK4VX – Popmedic

回答

29

不幸的是,沒有。沒有內建的方法來做到這一點。

作爲一個側面說明,你可以省略capacity參數在切片創建:

v := make([]string, len(m)) 

能力隱含爲相同長度在這裏。

28

作爲除了JIMT的帖子:

您也可以使用append而不是明確指定的值將其索引:

m := make(map[int]string) 

m[1] = "a" 
m[2] = "b" 
m[3] = "c" 
m[4] = "d" 

v := make([]string, 0, len(m)) 

for _, value := range m { 
    v = append(v, value) 
} 

注意,長度爲零(無元素目前還沒有),但容量(分配的空間)使用m的元素數進行初始化。這樣做使得append不需要每次切片v的容量用完時分配存儲器。

您也可以make切片沒有容量值,並讓append爲自己分配內存。

+0

我想知道這是否會更慢(假設前期分配)?我用map [int] int做了一個粗略的基準測試,看起來慢了1-2%。任何想法,如果這是擔心或只是去與它? – masebase

+1

我會假設追加速度稍慢,但在大多數情況下,這種差異可以忽略不計。 [比較直接轉讓和追加的基準](http://pastie.org/5393131)。 – nemo

0

據我目前所知,去沒有一種方法來連接字符串/字節到一個結果字符串,而不至少做兩個/副本。

由於所有字符串值都是常量,所以您當前必須增長[]字節,那麼您必須使用字符串內建語言來讓語言創建一個'祝福'字符串對象,它將複製緩衝區,可以引用支持[]字節的地址。

如果一個[]字節是合適的,那麼你可以在字節上獲得非常小的優勢。通過進行一次分配和執行副本來調用你自己的聯接功能。

package main 
import (
    "fmt" 
) 

func main() { 
m := make(map[int]string) 

m[1] = "a" ; m[2] = "b" ;  m[3] = "c" ; m[4] = "d" 

ip := 0 

/* If the elements of m are not all of fixed length you must use a method like this; 
* in that case also consider: 
* bytes.Join() and/or 
* strings.Join() 
* They are likely preferable for maintainability over small performance change. 

for _, v := range m { 
    ip += len(v) 
} 
*/ 

ip = len(m) * 1 // length of elements in m 
r := make([]byte, ip, ip) 
ip = 0 
for _, v := range m { 
    ip += copy(r[ip:], v) 
} 

// r (return value) is currently a []byte, it mostly differs from 'string' 
// in that it can be grown and has a different default fmt method. 

fmt.Printf("%s\n", r) 
} 
相關問題