当前位置: 首页 > 面试题库 >

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

魏勇军
2023-03-14
问题内容

我来自拥有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



 类似资料:
  • 我有一个数组对象形式的数据。我将根据日期和代码对数据进行分组和汇总 预期结果

  • 我有一个过程对象列表,如下所示 我的程序课就像 我想基于以下条件对对象进行排序和分组。 应根据过程名称对所有过程进行分组。 过程必须按过程日期降序排列。[日期列表中的第一个元素,即 分组在一起的相同过程应按日期降序排列。 最终结果必须是, 我能够使用比较器和旧的Java代码实现这一点。是否可以使用java8流、收集器和分组来实现相同的功能?

  • 我已经创建了一个bean类,其中包含所有字段(name、amount、description和number),以及相同的getter和setter。productBeans有所有产品的列表。 groupByProduct具有用名称分组的产品列表。结果给出了以产品地图为关键,以产品总量为价值的产品地图。 但在这里,我试图将产品和总金额映射到产品列表中。我试图结合上面的代码来获得预期的输出,但未能实现

  • 问题内容: 我在Postgres服务器上有以下数据库表: 我想创建一个查询,给出了的按月份和年份如下列并对结果进行分组: 有没有简单的方法可以做到这一点? 问题答案: 应Radu的要求,我将解释该查询: :将“日期”属性转换为月的简短形式的定义格式。 :Postgresql的“提取”功能用于从“日期”属性中提取YYYY年。 :SUM()函数将所有“ Sales”值相加,并提供区分大小写的别名,并使

  • 我有课 给出一个Person类列表,我根据该类的不同属性进行聚合。对于(如)- 现在我需要得到一个结果,这样我就应该根据国家和城市的组合得到总的“totalcountrytoCityCount”,并且根据国家、城市和宠物的组合得到总的“petCount”。我可以使用groupingBy和summingint分别获得它们 它给出了结果 但我想要的实际结果是:- 令人惊讶地删除了计数

  • 我有一个测试数据库,每个测试都有一个StartTime和(对于那些完成的)EndTime值。我想创建一个查询,显示每小时运行的测试数量。 i、 e.在任何给定时间有开始时间但没有结束时间的测试。 我解决了分组问题——感谢@p.cambell对问题SQL Server Group by Count of DateTime Per Hour的回答?