[go-nuts] slice of a map and how to sort it.

2,398 views
Skip to first unread message

german diago

unread,
May 12, 2010, 3:08:47 PM5/12/10
to golang-nuts
Hello. I would like if it's possible to get a slice from a
map[string]int .

I want to make a view from a map and I want to sort that view without
touching the map. Is this possible?

chris dollin

unread,
May 12, 2010, 3:16:27 PM5/12/10
to german diago, golang-nuts
Make a slice of the keys & sort the keys for the view. To make the
slice, make a slice of size len(theMap) and fill it in a map range loop.

Chris

--
Chris "new maps of Hell?" Dollin

german diago

unread,
May 12, 2010, 4:50:19 PM5/12/10
to golang-nuts

> Make a slice of the keys & sort the keys for the view. To make the
> slice, make a slice of size len(theMap) and fill it in a map range loop.

I found that solution. Thanks. But the problem now is that the range
loop
is EXTREMELY confusing.

type mapView struct {
key *string
value *int
}

mymap := map[string]int{...........}
view := make([]mapView, len(mymap), len(mymap))

for key, value := range mymap {
view[i] = mapView(&key, &value)
}

This won't work. key and value are copies and don't reference the key
and value from mymap. It's difficult to do
this in a straightforward way.

Daniel Smith

unread,
May 12, 2010, 4:53:21 PM5/12/10
to german diago, golang-nuts
Why do you want to store pointers in mapView?

You can get a pointer to the value with &mymap[key]. There's no way to get a pointer to the key inside the map (and would you really want to?).

Steven

unread,
May 12, 2010, 5:26:21 PM5/12/10
to dan...@lukenine45.net, german diago, golang-nuts
Is this what you're trying to do?

You can't take a pointer to a map value, or a map key. And there are no reference semantics in Go. Any time you do

x := y OR
x = y

you make a (shallow) copy. I don't see how this is confusing. Its consistent.

Why do you want a pointer into the map?

Brett Kail

unread,
May 12, 2010, 5:29:43 PM5/12/10
to golang-nuts
On May 12, 3:53 pm, Daniel Smith <dan...@lukenine45.net> wrote:
> You can get a pointer to the value with &mymap[key].

This is not accurate. Per the spec:

"The address-of operator & generates the address of its operand, which
must be addressable, that is, either a variable, pointer indirection,
array or slice indexing operation, or a field selector of an
addressable struct operand."

Allowing address-of on map entry values poses a problem for deleted
entries. Either it allows unsafe access to potentially freed memory
or it requires that the map implementation use distinct, GC-able map
entry objects.

Daniel Smith

unread,
May 12, 2010, 5:33:56 PM5/12/10
to Brett Kail, golang-nuts
Oops, my bad, sorry. I thought I had done that before but I must have been mistaken.


On Wed, May 12, 2010 at 4:29 PM, Brett Kail <bjk...@gmail.com> wrote:
This is not accurate.  Per the spec:



german diago

unread,
May 12, 2010, 5:54:33 PM5/12/10
to golang-nuts

> > Daniel Smith
> >http://www.schaumburggoclub.org/
>
> Is this what you're trying to do?http://ideone.com/vQCU3

Yes. Thanks. My background is C++. I was translating some code. A view
for a
map in c++ is done storing iterators to the entries of that map. But
as I see in go, the correct
way is to... copy the values?


> You can't take a pointer to a map value, or a map key. And there are no
> reference semantics in Go. Any time you do
> Why do you want a pointer into the map?

I wanted a pointer into the map because is what I do in c++. Sorry, my
fault, it's how I did it.
Changing is difficult.

Steven

unread,
May 12, 2010, 6:08:14 PM5/12/10
to german diago, golang-nuts
On Wed, May 12, 2010 at 5:54 PM, german diago <germa...@gmail.com> wrote:

> > Daniel Smith
> >http://www.schaumburggoclub.org/
>
> Is this what you're trying to do?http://ideone.com/vQCU3

Yes. Thanks. My background is C++. I was translating some code. A view
for a
map in c++ is done storing iterators to the entries of that map. But
as I see in go, the correct
way is to... copy the values?

Yes, in Go, you're always making a copy. If your type is big enough that copying is expensive (no primitive type is worth it, and neither are small structs), you can store it as a pointer. Only use a pointer when you need a reference, or your type is really big. 

If you need to be able to alter the map externally, then you could use a map[string]*int, but its probably better to manipulate the map directly when you need to.

peterGo

unread,
May 12, 2010, 6:33:07 PM5/12/10
to golang-nuts
german,

package main

import (
"fmt"
"sort"
)

func main() {
m := map[string]int{"one": 1, "two": 2, "three": 3}
v := make([]string, len(m))
i := 0
for k, _ := range m {
v[i] = k
i++
}
sort.SortStrings(v)
fmt.Println(v)
}

Peter

german diago

unread,
May 12, 2010, 6:36:18 PM5/12/10
to golang-nuts

> copying is expensive (no primitive type is worth it, and neither are small
> structs), you can store it as a pointer. Only use a pointer when you need a
> reference, or your type is really big.

I was exactly wondering what to do in that situation. So I can point
to some struct
as long as I allocate it with new because even if I store it in a map,
when the map
changes its layout, the pointer will be the same, I think.
Reply all
Reply to author
Forward
0 new messages