2017-07-27 101 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

在文章中,切片是通过在地图上迭代构建的,因此切片将以随机顺序填充。他对切片进行了排序,以便按键始终按照相同的数字升序排列。 切片中条目的顺序是固定的。如果您删除排序命令并添加循环的很多副本,则会看到返回地图中相同元素的顺序。你只是不知道这个顺序会是什么,因为密钥将被添加到切片的顺序是随机的。 –