英文:
Using variable-length array as a map key in golang
问题
我找不到一个好的方法来做这个。我想要从一个排序的键值对列表创建一个映射。
type Tag struct {
key string
value string
}
type SortedTag []Tag // 排序的标签列表
map[SortedTags]T // 无法实现
我可以通过使用分隔符连接所有的键值对来解决这个问题,但我觉得这种方法在很多方面都是低效和容易出错的。将其转换回键值对很麻烦,因为我们需要拆分输入。此外,如果键值对可以是任意值,那么我们就需要进行转义。
如果是在Python中,我会将Tag
存储为排序的2元组的N元组。
如果是在Java中,我会创建一个复合对象,其中包含Map<String, String>
,并使用equals()
方法与其他哈希映射进行比较,hashCode()
方法返回映射的所有哈希值的异或值(使用异或是因为它是可交换的,因此我们可以以任意顺序迭代映射来计算这个值)。
在Go中,我想不到其他好的方法。
英文:
I can't find a good way to do this. I want to have a map from a list of sorted key-value pairs.
type Tag struct {
key string
value string
}
type SortedTag []Tag // sorted list of tags.
map[SortedTags]T // cannot do.
I can solve this problem by joining all the key-value pairs with a delimiter, but I feel like this is inefficient and error prone in many ways. Converting back to the key-value pair is cumbersome because we need to split the input. moreover, if the key value pair can be anything, that means we have to escape it.
If it was python, I would've stored Tag
as N-tuple of sorted 2-tupless.
If it was java, I would've created a composite object with Map<String,String>
with equals()
checking against the other hash map, hashCode()
returning the xor
of all the hashes of the map (xor
since it is commutative thus we can iterate the map in any order to compute this value).
In go, I can't think of any other good way.
答案1
得分: 3
例如,
package main
import "fmt"
type Tag struct {
Key string
Value string
}
type Tags []Tag
type TagsValue struct {
// 作为 Tags 值的某些类型
}
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: {}
如果你只是想测试 Tags 是否属于集合,
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)
}
// 在集合中
fmt.Println(m.IsMember(sortedTags))
// 不在集合中
sortedTags[0].Key = "key0"
fmt.Println(m.IsMember(sortedTags))
}
输出:
Tags Key: key1value1key7value7key7value49key42value42
Tags: [{key1 value1} {key7 value7} {key7 value49} {key42 value42}]
true
false
英文:
For example,
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)
}
}
Output:
Tags Key: key1value1key7value7key7value49key42value42
Tags: [{key1 value1} {key7 value7} {key7 value49} {key42 value42}]
Tags Value: {}
If you are simply trying to test for Tags set membership,
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))
}
Output:
Tags Key: key1value1key7value7key7value49key42value42
Tags: [{key1 value1} {key7 value7} {key7 value49} {key42 value42}]
true
false
答案2
得分: 0
如果你想要(排序的)元组,你可以查看kmanley/golang-tuple。
它有排序元组的示例。
这与deckarep/golang-set不同,后者对于管理那些Tag
也很有帮助。
英文:
if you are after (sorted) tuples, you can check out kmanley/golang-tuple
It does have examples of sorting tuples.
This is different from deckarep/golang-set, which can also be helpful for managing those Tag
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论