最常用的将结构体分组的方式是什么?

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

Most idiomatic way to group structs?

问题

我正在为你翻译以下内容:

我正在尝试通过多个键将一组结构体分组在一起。在下面的示例中,猫根据它们的年龄和名称作为键进行分组。Go中是否有更符合惯用法、通用或更好的方法来做到这一点?

我需要对不同结构体的多种类型应用“group by”,因此可能会变得非常冗长。

package main

import (
	"errors"
	"fmt"
	"math/rand"
)

type Cat struct {
	CatKey
	Kittens int
}

type CatKey struct {
	Name string
	Age  int
}

func NewCat(name string, age int) *Cat {
	return &Cat{CatKey: CatKey{Name: name, Age: age}, Kittens: rand.Intn(10)}
}

func GroupCatsByNameAndAge(cats []*Cat) map[CatKey][]*Cat {
	groupedCats := make(map[CatKey][]*Cat)
	for _, cat := range cats {
		if _, ok := groupedCats[cat.CatKey]; ok {
			groupedCats[cat.CatKey] = append(groupedCats[cat.CatKey], cat)
		} else {
			groupedCats[cat.CatKey] = []*Cat{cat}
		}
	}

	return groupedCats
}

func main() {
	cats := []*Cat{
		NewCat("Leeroy", 12),
		NewCat("Doofus", 14),
		NewCat("Leeroy", 12),
		NewCat("Doofus", 14),
		NewCat("Leeroy", 12),
		NewCat("Doofus", 14),
		NewCat("Leeroy", 12),
		NewCat("Doofus", 14),
		NewCat("Leeroy", 12),
		NewCat("Doofus", 14),
	}

	groupedCats := GroupCatsByNameAndAge(cats)

	Assert(len(groupedCats) == 2, "Expected 2 groups")
	for _, value := range groupedCats {
		Assert(len(value) == 5, "Expected 5 cats in 1 group")
	}

	fmt.Println("Success")
}

func Assert(b bool, msg string) {
	if !b {
		panic(errors.New(msg))
	}
}

希望对你有帮助!

英文:

I'm trying to group together a set of structs by multiple keys. In the example below, cats are grouped together with their age and name used as the key. Is there a more idiomatic, generic or just a better way to do this in Go?

I need to apply "group by" for multiple types of different structs, so this could get very verbose.

http://play.golang.org/p/-CHDQ5iPTR

package main
import (
"errors"
"fmt"
"math/rand"
)
type Cat struct {
CatKey
Kittens int
}
type CatKey struct {
Name string
Age  int
}
func NewCat(name string, age int) *Cat {
return &Cat{CatKey: CatKey{Name: name, Age: age}, Kittens: rand.Intn(10)}
}
func GroupCatsByNameAndAge(cats []*Cat) map[CatKey][]*Cat {
groupedCats := make(map[CatKey][]*Cat)
for _, cat := range cats {
if _, ok := groupedCats[cat.CatKey]; ok {
groupedCats[cat.CatKey] = append(groupedCats[cat.CatKey], cat)
} else {
groupedCats[cat.CatKey] = []*Cat{cat}
}
}
return groupedCats
}
func main() {
cats := []*Cat{
NewCat("Leeroy", 12),
NewCat("Doofus", 14),
NewCat("Leeroy", 12),
NewCat("Doofus", 14),
NewCat("Leeroy", 12),
NewCat("Doofus", 14),
NewCat("Leeroy", 12),
NewCat("Doofus", 14),
NewCat("Leeroy", 12),
NewCat("Doofus", 14),
}
groupedCats := GroupCatsByNameAndAge(cats)
Assert(len(groupedCats) == 2, "Expected 2 groups")
for _, value := range groupedCats {
Assert(len(value) == 5, "Expected 5 cats in 1 group")
}
fmt.Println("Success")
}
func Assert(b bool, msg string) {
if !b {
panic(errors.New(msg))
}
}

答案1

得分: 2

这是GroupCatsByNameAndAge函数的更加惯用的版本。请注意,如果groupedCats没有cat.CatKey,那么groupedCats[cat.CatKey]将是nil,然而nilappend函数的一个完全可接受的值。Playground

func GroupCatsByNameAndAge(cats []*Cat) map[CatKey][]*Cat {
    groupedCats := make(map[CatKey][]*Cat)
    for _, cat := range cats {
        groupedCats[cat.CatKey] = append(groupedCats[cat.CatKey], cat)
    }
    return groupedCats
}
英文:

Here is a more idiomatic version of the GroupCatsByNameAndAge function. Note that a if groupedCats doesn't have a cat.CatKey then groupedCats[cat.CatKey] will be nil, however nil is a perfectly acceptable value for append. Playground

func GroupCatsByNameAndAge(cats []*Cat) map[CatKey][]*Cat {
groupedCats := make(map[CatKey][]*Cat)
for _, cat := range cats {
groupedCats[cat.CatKey] = append(groupedCats[cat.CatKey], cat)
}
return groupedCats
}

huangapple
  • 本文由 发表于 2014年3月10日 02:33:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/22286308.html
匿名

发表评论

匿名网友

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

确定