-1

I want to store some values in hashmap without index name. I mean derived from the array and hashmap.

Example :

{"name":"attn",1,5,6,7,8}

Output of variable (just for demonstration):

( "name" : "attn", 0:1, 1:5, 2:6, 3:7, 4:8, )

Or another example:

{ 0:"start","name":"mattn","age":39,"child":[1,2,3,4,5,9:1] }

How can do this in Go?

Maybe I need new data type? :)

Please, help me! Thank you!

icza
  • 389,944
  • 63
  • 907
  • 827
Love Python
  • 25
  • 2
  • 4
  • I don't think you can do anything like this in Go. Go strives to be explicit, so you must always provide keys in maps. – Ainar-G Jan 31 '17 at 09:57
  • The post is highly ambiguous. Your code is not Go code. Read about strict typing languages, because Go is not Python... Not even close... – I159 Jan 31 '17 at 09:58
  • Why minuses? It's a typical novice question coming from dynamic typing languages. Except for "child":[1,2,3,4,5,9:1] - everything is doable in go – Alex Yu Jan 31 '17 at 10:11

2 Answers2

2

Spec: Composite literals:

The key is interpreted as a field name for struct literals, an index for array and slice literals, and a key for map literals. For map literals, all elements must have a key. It is an error to specify multiple elements with the same field name or constant key value.

So no, using a composite literal to initialize a map, we can't omit the keys.

We may (and usually we do) omit indices when using a slice literal. So we may list key-value pairs in one map literal (where we know or want to explicitly state the key), and list elements with subsequent indices in another slice literal to initialize a slice. Then we can iterate over the slice and add key-value pairs based on index-value pairs.

Your first example:

m := map[interface{}]interface{}{
    "name": "attn",
}
s := []int{1, 5, 6, 7, 8}
for i, v := range s {
    m[i] = v
}
fmt.Println(m)

Output:

map[0:1 1:5 2:6 3:7 4:8 name:attn]

Your other example:

m = map[interface{}]interface{}{
    0: "start", "name": "mattn", "age": 39,
    "child": []int{1: 1, 2, 3, 4, 5, 9: 1},
}
fmt.Println(m)

Output:

map[0:start name:mattn age:39 child:[0 1 2 3 4 5 0 0 0 1]]

Try these on the Go Playground.

Note that in the 2nd example the value for "child" is a slice which contains 0 elements. The reason for this is because a slice or array is contiguous, even if we don't provide elements for all indices, there will still be elements for the missing indices. If we don't want this, that is not a slice (or array), but that is a map, and we can initialize it as seen in the first example.

We can't distinguish between an implicit 0 and an explicit 0 (which we may list in the composite literal). If 0 is a value we may use, another alternative would be to define type of child to be []interface{}, and if we don't explicitly specify a value in the composite literal, it will be nil.

See this question for more examples on initializing arrays and slices: Keyed items in golang array initialization

Community
  • 1
  • 1
icza
  • 389,944
  • 63
  • 907
  • 827
1

You can do something like this:

package main

import "fmt"

func main() {
    dynMap := map[interface{}]interface{}{
        "name": "attn",
        0:      1,
        1:      5,
        2:      6,
        3:      7,
        4:      8,
    }
    fmt.Printf("%v\n", dynMap)

    dynMap2 := map[interface{}]interface{}{
        0:       "start",
        "name":  "mattn",
        "age":   39,
        "child": []int{1, 2, 3, 4, 5, 9:1}, 

    }
    fmt.Printf("%v\n", dynMap2)
}

Except for "child":[1,2,3,4,5,9:1] - I fail to understand what you really want for [9:1] Thanks for correction: this is also doable.

And, although I like python too, go is not python (or js/ruby/etc). If you will do a lot interface{} and reflect on it - it's possible but it's a pain.

Alex Yu
  • 3,412
  • 1
  • 25
  • 38