Iterate Struct (map key) value in golang

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

Iterate Struct (map key) value in golang

问题

我已经查阅了在Golang中将结构体作为map键

我了解在Golang中遍历map时没有保证的顺序。我按照Golang博客中的示例尝试使用struct作为map的键。

以下是我的代码:

package main

import (
	"fmt"
	"sort"
)

func main() {
	req := make(map[mapKey]string)

	req[mapKey{1, "r"}] = "rob pike"
	req[mapKey{2, "gri"}] = "robert griesemer"
	req[mapKey{3, "adg"}] = "andrew gerrand"
	req[mapKey{4, "rsc"}] = "russ cox"

	var keys []mapKey
	for k := range req {
		keys = append(keys, k)
	}

	for _, k := range keys {
		fmt.Printf("short name: %s, long name: %s\n", k.Option, req[k])
	}

	sort.Slice(keys, func(i, j int) bool {
		return keys[i].Key < keys[j].Key
	})
}

我希望结果如下所示:

short name: r, long name: rob pike
short name: gri, long name: robert griesemer
short name: adg, long name: andrew gerrand
short name: rsc, long name: russ cox

我不知道如何将结构体的值和键分别迭代到不同的数据结构中。

英文:

I've looked up Structs as keys in Golang maps

I understand iteration over the maps in golang has no guaranteed order. I've followed the example in golang blog, and tried using a struct as a map key.

Here's my code

package main

func main() {
	req := make(map[mapKey]string)

	req[mapKey{1, &quot;r&quot;}] = &quot;robpike&quot;
	req[mapKey{2, &quot;gri&quot;}] = &quot;robert griesemer&quot;
	req[mapKey{3, &quot;adg&quot;}] = &quot;andrew gerrand&quot;
	req[mapKey{4, &quot;rsc&quot;}] = &quot;russ cox&quot;

	var keys []int
	for k := range req {
		keys = append(keys, k.Key)
	}

	for _, k := range keys {
		fmt.Printf(&quot;short name : %s , long name : %s\n&quot;,req[k], req[k]) // How do I iterate here
	}

	sort.Ints(keys)
}

type mapKey struct {
	Key    int
	Option string
}

What I want the results to be is

short name : r , long name : rob pike
short name : gri , long name : robert griesemer
short name : adg , long name : andrew gerrand
short name : rsc , long name : russ cox

And I don't know how I can get the struct value and key iterated by separated data structure.

答案1

得分: 3

简短版本?你不能用那种方式做。

长版本中,你可以使用自定义排序器:

func main() {
    req := make(map[mapKey]string)

    req[mapKey{1, "r"}] = "robpike"
    req[mapKey{2, "gri"}] = "robert griesemer"
    req[mapKey{3, "adg"}] = "andrew gerrand"
    req[mapKey{4, "rsc"}] = "russ cox"

    var keys mapKeys
    for k := range req {
        keys = append(keys, k)
    }
    sort.Sort(keys)
    for _, k := range keys {
        fmt.Printf("short name : %s , long name : %s\n", k.Option, req[k])
    }
}

type mapKey struct {
    Key    int
    Option string
}

type mapKeys []mapKey

func (mk mapKeys) Len() int           { return len(mk) }
func (mk mapKeys) Swap(i, j int)      { mk[i], mk[j] = mk[j], mk[i] }
func (mk mapKeys) Less(i, j int) bool { return mk[i].Key < mk[j].Key }

请注意,如果你的mapKey结构体有一个不支持相等性比较的字段(比如结构体或切片),使用req[k]将无法工作。

在这种情况下,你可以切换到type mapKeys []*mapKeymap[*mapKey]string

英文:

Short version? You can't do it that way.

Long version you, you can use a custom sorter:

func main() {
	req := make(map[mapKey]string)

	req[mapKey{1, &quot;r&quot;}] = &quot;robpike&quot;
	req[mapKey{2, &quot;gri&quot;}] = &quot;robert griesemer&quot;
	req[mapKey{3, &quot;adg&quot;}] = &quot;andrew gerrand&quot;
	req[mapKey{4, &quot;rsc&quot;}] = &quot;russ cox&quot;

	var keys mapKeys
	for k := range req {
		keys = append(keys, k)
	}
	sort.Sort(keys)
	for _, k := range keys {
		fmt.Printf(&quot;short name : %s , long name : %s\n&quot;, k.Option, req[k])
	}
}

type mapKey struct {
	Key    int
	Option string
}

type mapKeys []mapKey

func (mk mapKeys) Len() int           { return len(mk) }
func (mk mapKeys) Swap(i, j int)      { mk[i], mk[j] = mk[j], mk[i] }
func (mk mapKeys) Less(i, j int) bool { return mk[i].Key &lt; mk[j].Key }

<kbd>play</kbd>

Keep in mind that if your mapKey struct have a field that doesn't support equality (aka a struct or a slice) using req[k] won't work.

In that case you can switch to type mapKeys []*mapKey and map[*mapKey]string.

huangapple
  • 本文由 发表于 2015年2月13日 16:52:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/28495679.html
匿名

发表评论

匿名网友

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

确定