Golang中的map打印顺序不一致

12
为什么地图是无序打印的,我应该如何使它有序?
package main

import (
    "fmt"
)

type monthsType struct {
    no   int
    text string
}

var months = map[int]string{
    1:"January", 2:"Fabruary", 3:"March", 4:"April", 5:"May", 6:"June",
    7:"July", 8:"August", 9:"September", 10:"October", 11:"Novenber", 12:"December",
}

func main(){
    for no, month := range months {
        fmt.Print(no)
        fmt.Println("-" + month)
    }
}

打印输出:

10-October
7-July
1-January
9-September
4-April
5-May
2-Fabruary
12-December
11-Novenber
6-June
8-August
3-March

1
可能是Google Go Lang分配顺序的重复问题。 - Denys Séguret
10
请注意,所有基于哈希表的集合在任何语言中都是一样的:哈希过程会导致顺序丢失。 - Denys Séguret
1
@dystroy:除了“有序”的哈希表数据结构之外。 - newacct
@newacct它们不是“哈希表”,通常是两个数据结构,一个哈希表和一个数组。 - Denys Séguret
有序映射或字典在其他语言中通常实现为树(RB 树很受欢迎),而无序映射通常为哈希表。例如,可以参考 std::map vs std::unordered_map。http://www.cplusplus.com/reference/map/map/ 和 http://www.cplusplus.com/reference/unordered_map/unordered_map/。 - Ionoclast Brigham
1
可能是按键排序golang映射值的重复问题 - Jonathan Hall
3个回答

17

代码:

func DemoSortMap() (int, error) {
    fmt.Println("use an array to access items by number:")
    am := [2]string{"jan", "feb"}
    for i, n := range am {
        fmt.Printf("%2d: %s\n", i, n)
    }
    fmt.Println("maps are non-sorted:")
    mm := map[int]string{2: "feb", 1: "jan"}
    for i, n := range mm {
        fmt.Printf("%2d: %s\n", i, n)
    }
    fmt.Println("access items via sorted list of keys::")
    si := make([]int, 0, len(mm))
    for i := range mm {
        si = append(si, i)
    }
    sort.Ints(si)
    for _, i := range si {
        fmt.Printf("%2d: %s\n", i, mm[i])
    }

    return 0, nil
}

(其中大部分内容来自M. Summerfield的书籍

输出:

use an array to access items by number:
 0: jan
 1: feb
maps are non-sorted:
 2: feb
 1: jan
access items via sorted list of keys::
 1: jan
 2: feb

6

地图是无序的,所以您可以使用切片来对地图进行排序。Mark Summerfield的书 "Programming in Go" 在第204页上解释了这一点,并且强烈推荐阅读。


1

这是一个很晚的回答,但从我所读的内容来看,地图设计上是未排序的,并且是随机的,因为人们不应该依赖于顺序。

除了使用sort包与第二个map一起使用外,还可以使用fmt.Prinln(theMap),它将按排序后的方式打印地图。

fmt:以键排序的方式打印地图

这通常会按以下方式打印地图:

map[key:value
key:value
key:value
]

但这可能不是你想要的...

通过使用fmt.Sprint,如果需要,可以操纵字符串。

例如:

s := fmt.Sprint(theMap)
s1 := s[4 : len(s)-1] // remove map[ and ]
fmt.Println(s1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接