英文:
How to define a map of sets in Go?
问题
我想知道如何在Go语言中定义一个集合的映射。集合是一个无序唯一元素的集合。
这些集合是一个结构体(Tile)的集合。
映射的键是一个字符串。键是tile.X + "," + tile.Y的组合。
目前我有的代码只适用于一个元素,而不是一个集合。
type Tile struct {
X int
Y int
}
func (t Tile) GetKey() string {
return strconv.Itoa(t.X) + "," + strconv.Itoa(t.Y)
}
// 这只适用于一个元素,而不是一个集合。
type Cache map[string]Tile
英文:
I would like to know how to define a map of sets in Go. A set is a collection of unordered unique elements.
The sets are collections of a struct (Tile).
The key of the map is a string. The key is the combination of tile.X + "," + tile.Y.
What I have so far. It only works for one element, not a set.
type Tile struct {
X int
Y int
}
func (t Tile) GetKey() {
return strconv.Itoa(t.X) + "," + strconv.Itoa(t.Y)
}
// This only works for one element, not for a set.
type Cache map[string]Tile
答案1
得分: 1
如何表示一个集合
在Go语言中,集合通常使用从给定类型到定义其存在的原始值的映射来表示。map
类型可以语义化地表示一个无序的唯一元素的集合。
var tileSet map[Tile]bool
请注意,你可以使用非指针的Tile
结构作为映射的键,因为:
如果所有字段都是可比较的,那么结构值是可比较的。如果对应的非空字段相等,那么两个结构值是相等的。
显然,X
和Y
这两个int
字段是可比较的。
这是如何使用这样的映射:
tileSet = make(map[Tile]bool, 0)
tile := Tile{X: 1, Y: 2}
tileSet[tile] = true
// 检查元素是否存在
if exists := tileSet[tile]; exists {
// ...
}
// 遍历集合元素
for tile, _ := range tileSet {
// ...
}
如何表示一个映射的集合
很简单:
var tileSetMap map[string]map[Tile]bool
为了简化代码,你还可以定义自己的集合类型:
type TileSet map[Tile]bool
然后可以这样使用:
func main() {
var tileSetMap map[string]TileSet
// 使用make正常初始化
tileSetMap = make(map[string]TileSet, 0)
tileSetMap["foo"] = make(TileSet, 0)
tile := Tile{10, 20}
tileSetMap["foo"][tile] = true
fmt.Println(tileSetMap) // map[foo:map[{10 20}:true]]
}
Playground: https://play.golang.org/p/ObUo62SI3ih
[1] 规范:Map类型
键类型的操作数必须完全定义了相等运算符==和!=。
英文:
How to represent a set
Sets in Go are usually represented with maps from the given type to a primitive value that defines its existence. The map
type is how you can semantically represent an unordered collection of unique elements.
var tileSet map[Tile]bool
Note that you can use non-pointer Tile
structs as map keys. because:
- map keys must be comparable (Specs: Map Types)
Tile
, based on how you defined it, is comparable (Specs: Comparison Operators), in particular:
> Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
...and clearly the two int
fields X
and Y
are comparable.
This is how you use such a map:
tileSet = make(map[Tile]bool, 0)
tile := Tile{X:1,Y:2}
tileSet[tile] = true
// check existence
if exists := tileSet[tile]; exists {
// ...
}
// range over set elements
for tile, _ := range tileSet {
// ...
}
How to represent a map of set
Trivially:
var tileSetMap map[string]map[Tile]bool
To simplify the code, you can also define your own set type:
type TileSet map[Tile]bool
and then
func main() {
var tileSetMap map[string]TileSet
// you initialize it normally with make
tileSetMap = make(map[string]TileSet, 0)
tileSetMap["foo"] = make(TileSet, 0)
tile := Tile{10, 20}
tileSetMap["foo"][tile] = true
fmt.Println(tileSetMap) // map[foo:map[{10 20}:true]]
}
Playground: https://play.golang.org/p/ObUo62SI3ih
<hr>
[1] Specs: Map Types
> The comparison operators == and != must be fully defined for operands of the key type
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论