Could anyone suggest a better implementation of this function that basically merges two slices such as:
existingBonuses := []bonus.Bonus{
bonus.Bonus{
Type: "BonusA",
Count: 1,
},
bonus.Bonus{
Type: "BonusC",
Count: 2,
},
}
newBonuses := []bonus.Bonus{
bonus.Bonus{
Type: "BonusA",
Count: 1,
},
bonus.Bonus{
Type: "BonusB",
Count: 2,
},
}
The function should return:
[]bonus.Bonus{
bonus.Bonus{
Type: "BonusA",
Count: 2,
},
bonus.Bonus{
Type: "BonusB",
Count: 2,
},
bonus.Bonus{
Type: "BonusC",
Count: 2,
},
}
My off-the-dome implementation is:
func (u *User) mergeBonuses(bonuses []bonus.Bonus) {
result := make(map[string]int)
merged := append(u.Bonuses, bonuses...)
for _, b := range merged {
if _, ok := result[b.Type]; ok {
result[b.Type] += b.Count
} else {
result[b.Type] = b.Count
}
}
r := make([]bonus.Bonus, 0)
for k, v := range result {
b := bonus.Bonus{
Type: k,
Count: v,
}
r = append(r, b)
}
u.Bonuses = r
}
But I was wondering if someone could point out a better or more Golang-like way to do it. Specifically I feel there should be a way to do it avoiding the second loop.
评论:
jerf:
Ronniemanseaman:There's a bit you can remove, such as the fact you can just += an empty map entry because you'll start with the 0 value, but at its core, that's what you're looking at, yes. Go doesn't have the sort of basic functional programming tools that are in most modern languages.
jerf:So are you saying I can omit the entire else {} block?
Ronniemanseaman:The whole if. Leave just the true branch.
Thanks, that is good to know
