如何在Go中使用哈希映射(hashmap)存储没有索引名称的值?

huangapple go评论77阅读模式
英文:

How to store values in hashmap without index name using go?

问题

我想在哈希映射中存储一些没有索引名称的值,也就是从数组和哈希映射中派生出来的值。

示例:

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

变量的输出(仅用于演示):

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

或者另一个示例:

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

在Go中如何实现这个?

也许我需要新的数据类型? 如何在Go中使用哈希映射(hashmap)存储没有索引名称的值?

请帮助我!谢谢!

英文:

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? 如何在Go中使用哈希映射(hashmap)存储没有索引名称的值?

Please, help me! Thank you!

答案1

得分: 2

规范:复合字面量:

> 对于结构体字面量,键被解释为字段名;对于数组和切片字面量,键被解释为索引;对于映射字面量,键被解释为键。**对于映射字面量,所有元素都必须有键。**如果指定了具有相同字段名或常量键值的多个元素,则会出现错误。

所以,不能省略键来使用复合字面量初始化一个map

当使用切片字面量时,我们可以(通常也会)省略索引。因此,我们可以在一个映射字面量中列出键值对(我们知道或想要明确指定键),并在另一个切片字面量中列出具有后续索引的元素来初始化一个切片。然后,我们可以遍历切片并根据索引-值对添加键值对。

你的第一个例子:

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

输出:

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

你的另一个例子:

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

输出:

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

在第二个例子中,"child"的值是一个包含0个元素的切片。这是因为切片或数组是连续的,即使我们没有为所有索引提供元素,缺失索引仍然会有元素。如果我们不想要这个,那就不是切片(或数组),而是一个map,我们可以像第一个例子中那样初始化它。

我们无法区分隐式的0和显式的0(我们可以在复合字面量中列出)。如果0是我们可以使用的值,另一种选择是将child的类型定义为[]interface{},如果我们在复合字面量中没有明确指定一个值,它将是nil

请参阅此问题以获取有关初始化数组和切片的更多示例:https://stackoverflow.com/questions/36302441/keyed-items-in-golang-array-initialization/36302875#36302875

英文:

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: https://stackoverflow.com/questions/36302441/keyed-items-in-golang-array-initialization/36302875#36302875

答案2

得分: 1

你可以这样做:

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

除了"child": [1, 2, 3, 4, 5, 9:1]这一行,我无法理解你对[9:1]的真正需求。感谢你的更正:这也是可行的。

虽然我也喜欢Python,但Go不是Python(或JS/Ruby等)。如果你要频繁使用interface{}和反射,虽然可以实现,但会很麻烦。

英文:

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

<strike>Except for "child":[1,2,3,4,5,9:1] - I fail to understand what you really want for [9:1]</strike> 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.

huangapple
  • 本文由 发表于 2017年1月31日 17:43:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/41954173.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定