为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
翻翻过去那场雪 2021-08-23 17:37:14
我找不到这样做的好方法。我想从排序的键值对列表中获取映射。type Tag struct {  key   string  value string}type SortedTag []Tag // sorted list of tags.map[SortedTags]T // cannot do.我可以通过用分隔符连接所有键值对来解决这个问题,但我觉得这在很多方面效率低下且容易出错。转换回键值对很麻烦,因为我们需要拆分输入。此外,如果键值对可以是任何东西,那意味着我们必须逃避它。如果它是 python,我会存储Tag为排序的 2-tupless 的 N 元组。如果它是 java,我会创建一个复合对象,Map<String,String>并equals()检查另一个哈希映射,hashCode()返回映射xor的所有哈希值(xor因为它是可交换的,因此我们可以以任何顺序迭代映射来计算这个值) .在go中,我想不出任何其他的好方法。
查看完整描述

2 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

例如,


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


查看完整回答
反对 回复 2021-08-23
?
慕的地6264312

TA贡献1817条经验 获得超6个赞

如果你在(排序的)元组之后,你可以查看kmanley/golang-tuple

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

这与dekarep/golang-set 不同,后者也有助于管理这些Tag.


查看完整回答
反对 回复 2021-08-23
  • 2 回答
  • 0 关注
  • 315 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信