diff --git a/internal/dirtoexcel/dirtoexcel.go b/internal/dirtoexcel/dirtoexcel.go index 33bd9b5..12262f2 100644 --- a/internal/dirtoexcel/dirtoexcel.go +++ b/internal/dirtoexcel/dirtoexcel.go @@ -5,6 +5,7 @@ import ( "math" "os" "regexp" + "sort" "strconv" "strings" "time" @@ -29,7 +30,9 @@ type Value struct { Value float64 } -type Categories map[string][]Value +type Values []Value + +type Categories map[string]Values func (c Categories) Insert(company, value string) error { fValue, err := strconv.ParseFloat(value, 32) @@ -133,19 +136,16 @@ func Create(out, dir string) error { return fmt.Errorf("failed to create new sheet: %w", err) } - m := map[string]float64{} - for _, i := range item { - m[i.Company] += i.Value - } + item = CalcAndSort(item) valueLength := 0 - for k, v := range m { - if err := f.SetCellStr(cat, fmt.Sprintf("A%d", valueLength+1), k); err != nil { + for _, i := range item { + if err := f.SetCellStr(cat, fmt.Sprintf("A%d", valueLength+1), i.Company); err != nil { return fmt.Errorf("failed to set cell: %w", err) } - if err := f.SetCellFloat(cat, fmt.Sprintf("B%d", valueLength+1), v, 2, 64); err != nil { + if err := f.SetCellFloat(cat, fmt.Sprintf("B%d", valueLength+1), i.Value, 2, 64); err != nil { return fmt.Errorf("failed to set cell: %w", err) } @@ -220,3 +220,32 @@ func createCategoryChart(category string, length int, f *excelize.File) error { return nil } + +func CalcAndSort(v Values) Values { + n := Values{} + + for _, i := range v { + added := false + + for k, v := range n { + if i.Company == v.Company { + n[k].Value += i.Value + + added = true + + break + } + } + + if !added { + n = append(n, i) + } + } + + // Sorting for company names. + sort.SliceStable(n, func(i, j int) bool { + return n[i].Company < n[j].Company + }) + + return n +} diff --git a/internal/dirtoexcel/dirtoexcel_test.go b/internal/dirtoexcel/dirtoexcel_test.go index f33f748..d241809 100644 --- a/internal/dirtoexcel/dirtoexcel_test.go +++ b/internal/dirtoexcel/dirtoexcel_test.go @@ -124,3 +124,34 @@ func TestCategoriesInsert(t *testing.T) { is.Equal(dirtoexcel.Categories{"NonFood": []dirtoexcel.Value{{"AMAZON", 11.11}}}, m) } + +func TestCalcAndSort(t *testing.T) { + tables := []struct { + name string + input dirtoexcel.Values + expected dirtoexcel.Values + }{ + { + "00", + dirtoexcel.Values{ + dirtoexcel.Value{Company: "BAR", Value: 3}, + dirtoexcel.Value{Company: "ALDI", Value: 1}, + dirtoexcel.Value{Company: "ALDI", Value: 2}, + }, + dirtoexcel.Values{ + dirtoexcel.Value{Company: "ALDI", Value: 3}, + dirtoexcel.Value{Company: "BAR", Value: 3}, + }, + }, + } + + is := is.New(t) + + for _, tt := range tables { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + is.Equal(dirtoexcel.CalcAndSort(tt.input), tt.expected) + }) + } +}