英文:
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
,然而nil
是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
}
英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论