2017-07-27 148 views
-2

好吧,我認爲這可能是一個老問題,但我沒有找到任何東西在stackoverflow。在進行中,地圖上的迭代順序不保證可重現。所以,建議的方法是將密鑰放在一個切片中並對該切片進行排序。然後迭代該切片以從地圖檢索值,以便我們按順序獲取它們(因爲由鍵組成的切片已排序,所以將以可重現的順序排列)。所以這意味着切片需要排序,否則在切片上的迭代也不會給出可重複的順序。但是當我在操場上嘗試下面的代碼時,我總是發現迭代中維護的順序,然後在映射迭代的情況下,爲什麼鍵片需要排序?切片迭代順序在

func main() { 
    var mySlice = make([]string, 0) 
    mySlice = append(mySlice, "abcd") 
    mySlice = append(mySlice, "efgh") 
    mySlice = append(mySlice, "ijkl") 
    mySlice = append(mySlice, "mnop") 
    mySlice = append(mySlice, "qrst") 
    mySlice = append(mySlice, "uvwxyz") 
    for _, val := range mySlice { 
     fmt.Println(val) 
    } 
    fmt.Println(strings.Join(mySlice, "|")) 

} 

輸出:

abcd 
efgh 
ijkl 
mnop 
qrst 
uvwxyz 
abcd|efgh|ijkl|mnop|qrst|uvwxyz 
+0

您正在混合切片和地圖。 – Volker

回答

0

唯一的原因,你的切片排序是因爲您正在以已排序的順序追加項目。如果你在一個未排序順序是這樣

var mySlice = make([]string, 0) 
mySlice = append(mySlice, "mnop") 
mySlice = append(mySlice, "efgh") 
mySlice = append(mySlice, "uvwxyz") 
mySlice = append(mySlice, "ijkl") 
mySlice = append(mySlice, "abcd") 
mySlice = append(mySlice, "qrst") 

附加項目(或從一個地圖,這將是無序拉鍵填充片),然後在迭代順序將是未排序(一致,是的,但始終未排序)。因此,如果您的目標是使用切片以排序順序從地圖中拉出項目,那麼您需要先對切片進行排序,除非您可以保證切片項目已按已排序的順序插入。

1

切片或陣列將總是有一個固定的順序,即,它是如何在存儲器佈局。

您正在閱讀的文檔可能只是告訴您對切片進行排序,以便地圖輸出按排序順序。

你是對的,地圖的迭代順序是未定義的,因此每次執行時都會有所不同。如果您使用切片來迭代地圖,那麼它總是會以可靠的順序返回,即切片中的鍵的順序。

我建議你閱讀關於slices的信息。

編輯

如果有幫助,請考慮以下代碼來說明一個切片的排序無關,其順序是固定的:

words := map[int]string{ 
    0: "hello", 
    1: "there", 
    2: "goodbye", 
} 
keys:=[]int{2,0,1} 
for _, k := range keys { 
    // Will output in order: Goodbye, hello, there 
    fmt.Println("Key:", k, "Value:", words[k]) 
} 
+0

這是我想要分享的鏈接:https://nathanleclaire.com/blog/2014/04/27/a-surprising-feature-of-golang-that-c​​olored-me-impressed/它提到了對切片進行排序在迭代它之前,我們可以使用這些鍵。如果切片順序是固定的,那麼爲什麼需要將其全部排序? –

+0

在文章中,切片是通過在地圖上迭代構建的,因此切片將以隨機順序填充。他對切片進行了排序,以便按鍵始終按照相同的數字升序排列。 切片中條目的順序是固定的。如果您刪除排序命令並添加循環的很多副本,則會看到返回地圖中相同元素的順序。你只是不知道這個順序會是什麼,因爲密鑰將被添加到切片的順序是隨機的。 –