我来自拥有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 }
我以为:
有没有更好的方法或任何美观,有效且易于使用的库?
基本上,您的idXX字段是键,一个n元组。而money场要加总的数据。
idXX
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]int,Register.key作为映射键来对所有具有相同键(相同ID)的寄存器进行“分组”:
map[Key]int
Register.key
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]则会给您0(0该int类型的零值),并正确告知该键的“上一个”和是0到目前为止。
Key
m[key]
0
int
还要注意,Key可能是一个嵌入式领域中Register,而不是一个“正规”的领域,它并不重要,而这种方式,你可以参考idXX场,如果他们的一部分Register。
Register