Golang:对结构进行分组和求和

我来自拥有LINQ的.NET世界,因此我可以像在SQL中通常看到的那样进行内存中查询。

我要对该结构进行切片,希望将其按8个字段分组,然后对另一个整数字段求和。就像是:

type Register struct {

id1 int

id2 int

id3 int

id4 int

id5 int

id6 int

id7 int

id8 int

money int

}

我以为:

  • 创建一个Equal函数,以比较结构(那八个字

    段)。遍历我正在分析的集合。对于每个项目,

    检查它是否已经在哈希表中。如果存在=>我对字段求和。如果不是=>我将新项目添加到哈希表。

有没有更好的方法或任何美观,有效且易于使用的库?

回答:

基本上,您的idXX字段是键,一个n元组。而money场要加总的数据。

如果您稍微重构类型,则可以轻松完成此操作。仅将键放入结构中,因此可以将其用作地图中的键。结构值是可比较的:

如果结构的所有字段都是可比较的,则它们的值是可比较的。如果两个结构值对应的非空白字段相等,则它们相等。

因此,新类型为:

type Key struct {

id1 int

id2 int

id3 int

id4 int

id5 int

id6 int

id7 int

id8 int

}

type Register struct {

key Key

money int

}

要对和进行分组和计算总和,您可以使用map[Key]intRegister.key作为映射键来对所有具有相同键(相同ID)的寄存器进行“分组”:

regs := []*Register{

{Key{id1: 345}, 1500},

{Key{id1: 345, id2: 140}, 2700},

{Key{id1: 345, id2: 140}, 1300},

{Key{id1: 345}, 1000},

{Key{id3: 999}, 1000},

{Key{id3: 999}, 2000},

}

// calculate sum:

m := map[Key]int{}

for _, v := range regs {

m[v.key] += v.money

}

fmt.Println(m)

输出:

map[{345 0 0 0 0 0 0 0}:2500 {345 140 0 0 0 0 0 0}:4000 {0 0 999 0 0 0 0 0}:3000]

对于一个不错的输出:

fmt.Println("Nice output:")

for k, v := range m {

fmt.Printf("%+3v: %d\n", k, v)

}

输出:

Nice output:

{id1:345 id2: 0 id3: 0 id4: 0 id5: 0 id6: 0 id7: 0 id8: 0}: 2500

{id1:345 id2:140 id3: 0 id4: 0 id5: 0 id6: 0 id7: 0 id8: 0}: 4000

{id1: 0 id2: 0 id3:999 id4: 0 id5: 0 id6: 0 id7: 0 id8: 0}: 3000

这是一样容易和有效的。在Go Playground上尝试示例。

在地图中,我们不必检查其中Key是否已存在a

。之所以如此,是因为如果键不在映射中,则索引映射会产生映射值类型的零值。因此,在这种情况下,如果a

Key尚未在映射中,m[key]则会给您00int类型的零值),并正确告知该键的“上一个”和是0到目前为止。

还要注意,Key可能是一个嵌入式领域中Register,而不是一个“正规”的领域,它并不重要,而这种方式,你可以参考idXX场,如果他们的一部分Register

以上是 Golang:对结构进行分组和求和 的全部内容, 来源链接: utcz.com/qa/433164.html

回到顶部