在golang中使用可变长度数组作为映射键

  • 本文关键字:数组 映射 golang go
  • 更新时间 :
  • 英文 :


我找不到一个好方法来做到这一点。我想要一个排序键值对列表中的映射。

type Tag struct {
  key   string
  value string
}
type SortedTag []Tag // sorted list of tags.
map[SortedTags]T // cannot do.

我可以通过使用分隔符连接所有键值对来解决这个问题,但我觉得这在很多方面效率低下且容易出错。转换回键值对很麻烦,因为我们需要拆分输入。此外,如果键值对可以是任何东西,那就意味着我们必须逃离它。

如果是python,我会将Tag存储为排序的2元组的N元组。

如果是java,我会用Map<String,String>创建一个复合对象,equals()检查另一个哈希映射,hashCode()返回映射的所有哈希的xorxor,因为它是交换的,所以我们可以按任何顺序迭代映射来计算这个值)。

在围棋中,我想不出其他好办法了。

例如,

package main
import "fmt"
type Tag struct {
    Key   string
    Value string
}
type Tags []Tag
type TagsValue struct {
    // some type used as Tags value
}
type TagsMapValue struct {
    Tags
    TagsValue
}
type TagsMapKey string
type TagsMap map[TagsMapKey]TagsMapValue
func NewTagsMapKey(tags Tags) TagsMapKey {
    b := []byte{}
    for _, tag := range tags {
        b = append(b, tag.Key...)
        b = append(b, tag.Value...)
    }
    return TagsMapKey(b[:len(b)])
}
func (m *TagsMap) AddElement(tags Tags, tagsValue TagsValue) {
    mapKey := NewTagsMapKey(tags)
    mapValue := TagsMapValue{Tags: make(Tags, 0, len(tags)), TagsValue: tagsValue}
    i := 0
    for _, tag := range tags {
        key := string(mapKey[i : i+len(tag.Key)])
        i += len(tag.Key)
        value := string(mapKey[i : i+len(tag.Value)])
        i += len(tag.Value)
        mapValue.Tags = append(mapValue.Tags, Tag{Key: key, Value: value})
    }
    (*m)[mapKey] = mapValue
    return
}
func main() {
    m := make(TagsMap)
    sortedTags := Tags{
        {Key: "key1", Value: "value1"},
        {Key: "key7", Value: "value7"},
        {Key: "key7", Value: "value49"},
        {Key: "key42", Value: "value42"},
    }
    m.AddElement(sortedTags, TagsValue{})
    for k, v := range m {
        fmt.Println("Tags Key:", k)
        fmt.Println("   Tags:      ", v.Tags)
        fmt.Println("   Tags Value:", v.TagsValue)
    }
}

输出:

Tags Key: key1value1key7value7key7value49key42value42
   Tags:       [{key1 value1} {key7 value7} {key7 value49} {key42 value42}]
   Tags Value: {}

如果你只是想测试标签集成员资格,

package main
import "fmt"
type Tag struct {
    Key   string
    Value string
}
type Tags []Tag
type TagsSetKey string
type TagsSet map[TagsSetKey]Tags
func NewTagsSetKey(tags Tags) TagsSetKey {
    b := []byte{}
    for _, tag := range tags {
        b = append(b, tag.Key...)
        b = append(b, tag.Value...)
    }
    return TagsSetKey(b[:len(b)])
}
func (m *TagsSet) AddElement(tags Tags) {
    setKey := NewTagsSetKey(tags)
    setValue := make(Tags, 0, len(tags))
    i := 0
    for _, tag := range tags {
        key := string(setKey[i : i+len(tag.Key)])
        i += len(tag.Key)
        value := string(setKey[i : i+len(tag.Value)])
        i += len(tag.Value)
        setValue = append(setValue, Tag{Key: key, Value: value})
    }
    (*m)[setKey] = setValue
    return
}
func (m *TagsSet) IsMember(tags Tags) bool {
    return (*m)[NewTagsSetKey(tags)] != nil
}
func main() {
    m := make(TagsSet)
    sortedTags := Tags{
        {Key: "key1", Value: "value1"},
        {Key: "key7", Value: "value7"},
        {Key: "key7", Value: "value49"},
        {Key: "key42", Value: "value42"},
    }
    m.AddElement(sortedTags)
    for k, v := range m {
        fmt.Println("Tags Key:", k)
        fmt.Println("   Tags: ", v)
    }
    // In set
    fmt.Println(m.IsMember(sortedTags))
    // Not in set
    sortedTags[0].Key = "key0"
    fmt.Println(m.IsMember(sortedTags))
}

输出:

Tags Key: key1value1key7value7key7value49key42value42
   Tags:  [{key1 value1} {key7 value7} {key7 value49} {key42 value42}]
true
false

如果你在寻找(排序的)元组,你可以查看kmaley/golang元组

它确实有排序元组的例子。

这与deckarep/golang集合不同,后者也有助于管理这些Tag

最新更新