簡體   English   中英

Golang:對結構進行分組和求和

[英]Golang: group and sum slice of structs

我來自.NET世界,我有LINQ所以我可以進行內存查詢,就像我們在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
}

要對sum進行分組和計算,可以使用map[Key]int ,使用Register.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是否已經存在。 這是因為如果鍵不在地圖中,則索引地圖會產生地圖值類型的零值 所以在這種情況下,如果一個Key還沒有出現在地圖中, m[key]會給你00int類型的零值),正確告訴該鍵的“previous”總和到目前為止為0

另請注意, Key可能是Register嵌入字段而不是“常規”字段,這沒關系,這樣您可以將idXX字段稱為它們是Register一部分。

你可以試試go-linq: https//github.com/ahmetalpbalkan/go-linq/

它與c#linq類似,在您的情況下使用GroupBy和Aggregate

https://godoc.org/github.com/ahmetalpbalkan/go-linq#example-Query-GroupBy https://godoc.org/github.com/ahmetalpbalkan/go-linq#example-Query-Aggregate

偽代碼:

From(regs).GroupBy(merge ids to a string as group key).Select(use Aggregate or SumInts to sum money)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM