doufang8965
doufang8965
2017-07-27 09:28

切片迭代顺序

已采纳

Ok, i think this may be an old question, but i didn't find anything over the stackoverflow. In go , the iteration order over a map is not guranteed to be reproducible. So, the way suggest is to hold the keys in a slice and sort that slice. Then iterate over that slice to retrieve the values from the map, so that we get them in order(since slice composed of keys is sorted, so will be in reproducible order). So this goes to imply that the slice need be sorted else iteration over the slice will also not give reproducible order. But when i tried the below code in playground, i always found the order maintained in iteration, then in the map iteration case, why the slice of keys need to be sorted?

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, "|"))

}

Output:

abcd
efgh
ijkl
mnop
qrst
uvwxyz
abcd|efgh|ijkl|mnop|qrst|uvwxyz
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • dongyili5843 dongyili5843 4年前

    The only reason your slice is sorted is because you're appending items in already sorted order. If you appended items in an unsorted order like this

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

    (or populated a slice by pulling keys from a map, which would be unsorted), then the order on iteration would be unsorted (consistent, yes, but consistently unsorted). So, if your objective is to use the slice to pull items from a map in sorted order, then you need to first sort the slice, unless you can guarantee the slice items were inserted in an already sorted order.

    点赞 评论 复制链接分享
  • doushao1948 doushao1948 4年前

    A slice or array will always have a fixed order, i.e. how it is laid out in memory.

    The documentation you were reading was probably just telling you to sort the slice so that the map output is in sorted order.

    You are correct that the iteration order of a map is undefined and hence can be different each time it is performed. If you use a slice to iterate a map then it will always come back in a reliable order, i.e. the order of the keys in the slice.

    I suggest you have a read over the information about slices.

    EDIT

    If it helps, consider the following code to illustrate that the sorting of a slice has nothing to do with its order being fixed:

    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])
    }
    
    点赞 评论 复制链接分享

为你推荐