12

Why is the map printing out of order, and how do I get it in to order?

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

Prints out:

10-October
7-July
1-January
9-September
4-April
5-May
2-Fabruary
12-December
11-Novenber
6-June
8-August
3-March
RoboTamer
  • 3,474
  • 2
  • 39
  • 43
  • 1
    possible duplicate of [Google Go Lang Assignment Order](http://stackoverflow.com/questions/11853396/google-go-lang-assignment-order) – Denys Séguret Aug 24 '12 at 11:39
  • 10
    Note that this is the same for all hash table based collections in every language : the hashing process loses the order. – Denys Séguret Aug 24 '12 at 11:41
  • 1
    @dystroy: except for the "ordered" hash table data structures – newacct Aug 24 '12 at 19:54
  • @newacct they're not "hash table based" : they're usually two structures, a hash table and an array – Denys Séguret Aug 24 '12 at 19:55
  • Ordered maps or dictionaries are often implemented in other languages as trees (RB trees are popular), while unordered are usually a hash table. See e.g. std::map vs std::unordered_map. http://www.cplusplus.com/reference/map/map/ and http://www.cplusplus.com/reference/unordered_map/unordered_map/ – Ionoclast Brigham Aug 15 '14 at 18:24
  • 1
    Possible duplicate of [sort golang map values by keys](https://stackoverflow.com/questions/23330781/sort-golang-map-values-by-keys) – Jonathan Hall Jul 08 '18 at 09:26

3 Answers3

17

Code:

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
}

(most of it stolen from M. Summerfield's book)

output:

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
Ekkehard.Horner
  • 38,498
  • 2
  • 45
  • 96
6

Maps are not sorted so you may use a slice to sort your map. Mark Summerfield's book "Programming in Go" explains this on page 204 and is highly recommended.

Dave Rose
  • 93
  • 1
  • 4
1

This is very late answer, but from what I have read maps are unsorted by design, and are random as one should not rely on the order.

Besides using the sort package together with a second map, one can also use the fmt.Prinln(theMap), which will print the map sorted.

fmt: print maps in key-sorted order

This will print the map typically as follows:

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

But this might not be what you want...

By using the fmt.Sprint one can then manipulate the string if needed.

i.e.

s := fmt.Sprint(theMap)
s1 := s[4 : len(s)-1] // remove map[ and ]
fmt.Println(s1)
Wayne
  • 3,359
  • 3
  • 30
  • 50