11# gofn
2- ![ Coverage] ( https://img.shields.io/badge/Coverage-87 .7%25-brightgreen )
2+ ![ Coverage] ( https://img.shields.io/badge/Coverage-88 .7%25-brightgreen )
33[ ![ Go] ( https://github.com/devalexandre/gofn/actions/workflows/go.yml/badge.svg )] ( https://github.com/devalexandre/gofn/actions/workflows/go.yml )
44
55# library to use golang functional
3131 - [ array.Shift] ( #arrayshift )
3232 - [ array.Sort] ( #arraysort )
3333 - [ array.GroupBy] ( #arraygroupby )
34+ - [ array.GroupSumBy] ( #arraygroupsumby )
35+ - [ array.GroupSumByWhere] ( #arraygroupsumbywhere )
36+ - [ array.GroupCountBy] ( #arraygroupcountby )
37+ - [ array.GroupReduceBy] ( #arraygroupreduceby )
38+ - [ array.GroupStatsBy] ( #arraygroupstatsby )
39+ - [ array.DistinctBy] ( #arraydistinctby )
40+ - [ array.IndexBy] ( #arrayindexby )
41+ - [ array.Partition] ( #arraypartition )
42+ - [ array.SortBy] ( #arraysortby )
43+ - [ array.Take, array.Skip, array.Chunk] ( #arraytake-arrayskip-arraychunk )
3444 - [ chaining functions] ( #chaining-functions )
3545
3646
@@ -379,6 +389,160 @@ type Itens struct {
379389 fmt.Println (len (grouped)) // 4
380390
381391```
392+
393+ ### array.GroupSumBy
394+ Group items by a key and sum a numeric value for each group.
395+
396+ ``` go
397+ type Itens struct {
398+ Name string
399+ Price float64
400+ Description string
401+ Qty int
402+ }
403+
404+ itens := []Itens {
405+ {" Item 1" , 10.0 , " Description 1" , 1 },
406+ {" Item 2" , 20.0 , " Description 2" , 2 },
407+ {" Item 3" , 30.0 , " Description 3" , 3 },
408+ {" Item 4" , 40.0 , " Description 4" , 10 },
409+ {" Item 4" , 40.0 , " Description 4" , 15 },
410+ {" Item 4" , 40.0 , " Description 4" , 25 },
411+ }
412+
413+ priceByName := array.GroupSumBy (itens,
414+ func (item Itens ) string { return item.Name },
415+ func (item Itens ) float64 { return item.Price },
416+ )
417+
418+ qtyByName := array.GroupSumBy (itens,
419+ func (item Itens ) string { return item.Name },
420+ func (item Itens ) int { return item.Qty },
421+ )
422+
423+ fmt.Println (priceByName[" Item 4" ]) // 120
424+ fmt.Println (qtyByName[" Item 4" ]) // 50
425+ ```
426+
427+ ### array.GroupSumByWhere
428+ Filter, group and sum in one pass.
429+
430+ ``` go
431+ priceByName := array.GroupSumByWhere (itens,
432+ func (item Itens ) bool { return item.Qty > 3 },
433+ func (item Itens ) string { return item.Name },
434+ func (item Itens ) float64 { return item.Price },
435+ )
436+
437+ fmt.Println (priceByName[" Item 4" ]) // 120
438+ ```
439+
440+ ### array.GroupCountBy
441+ Count rows by a key.
442+
443+ ``` go
444+ countByName := array.GroupCountBy (itens, func (item Itens ) string {
445+ return item.Name
446+ })
447+
448+ fmt.Println (countByName[" Item 4" ]) // 3
449+ ```
450+
451+ ### array.GroupReduceBy
452+ Build custom summaries by group.
453+
454+ ``` go
455+ type Summary struct {
456+ TotalPrice float64
457+ TotalQty int
458+ }
459+
460+ summaryByName := array.GroupReduceBy (itens,
461+ func (item Itens ) string {
462+ return item.Name
463+ },
464+ func (acc Summary , item Itens ) Summary {
465+ acc.TotalPrice += item.Price
466+ acc.TotalQty += item.Qty
467+ return acc
468+ },
469+ )
470+
471+ fmt.Println (summaryByName[" Item 4" ]) // {120 50}
472+ ```
473+
474+ ### array.GroupStatsBy
475+ Calculate count, sum, min, max and average by group.
476+
477+ ``` go
478+ statsByName := array.GroupStatsBy (itens,
479+ func (item Itens ) string { return item.Name },
480+ func (item Itens ) float64 { return item.Price },
481+ )
482+
483+ fmt.Println (statsByName[" Item 4" ].Count ) // 3
484+ fmt.Println (statsByName[" Item 4" ].Sum ) // 120
485+ fmt.Println (statsByName[" Item 4" ].Avg ) // 40
486+ ```
487+
488+ ### array.DistinctBy
489+ Keep the first row for each key.
490+
491+ ``` go
492+ uniqueByName := array.DistinctBy (itens, func (item Itens ) string {
493+ return item.Name
494+ })
495+
496+ fmt.Println (len (uniqueByName)) // 4
497+ ```
498+
499+ ### array.IndexBy
500+ Create a map by key. If a key repeats, the last row wins.
501+
502+ ``` go
503+ itemByName := array.IndexBy (itens, func (item Itens ) string {
504+ return item.Name
505+ })
506+
507+ fmt.Println (itemByName[" Item 4" ].Qty ) // 25
508+ ```
509+
510+ ### array.Partition
511+ Split rows into matched and unmatched slices.
512+
513+ ``` go
514+ highQty , lowQty := array.Partition (itens, func (item Itens ) bool {
515+ return item.Qty > 3
516+ })
517+
518+ fmt.Println (len (highQty)) // 3
519+ fmt.Println (len (lowQty)) // 3
520+ ```
521+
522+ ### array.SortBy
523+ Sort rows by a selected field without mutating the original slice.
524+
525+ ``` go
526+ byQty := array.SortBy (itens, func (item Itens ) int {
527+ return item.Qty
528+ })
529+
530+ fmt.Println (byQty[0 ].Qty ) // 1
531+ ```
532+
533+ ### array.Take, array.Skip, array.Chunk
534+ Use these helpers for pagination and batch processing.
535+
536+ ``` go
537+ firstPage := array.Take (itens, 2 )
538+ nextRows := array.Skip (itens, 2 )
539+ batches := array.Chunk (itens, 2 )
540+
541+ fmt.Println (len (firstPage)) // 2
542+ fmt.Println (len (nextRows)) // 4
543+ fmt.Println (len (batches)) // 3
544+ ```
545+
382546## chaining functions
383547
384548You can chain the functions together.
@@ -398,3 +562,60 @@ data := array.Array[int]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
398562 fmt.Println (a) // [4 8 12 16 20]
399563
400564```
565+
566+ You can also group and sum values after filtering.
567+
568+ ``` go
569+ type Itens struct {
570+ Name string
571+ Price float64
572+ Description string
573+ Qty int
574+ }
575+
576+ data := array.Array [Itens]{
577+ {" Item 1" , 10.0 , " Description 1" , 1 },
578+ {" Item 2" , 20.0 , " Description 2" , 2 },
579+ {" Item 3" , 30.0 , " Description 3" , 3 },
580+ {" Item 4" , 40.0 , " Description 4" , 10 },
581+ {" Item 4" , 40.0 , " Description 4" , 15 },
582+ {" Item 4" , 40.0 , " Description 4" , 25 },
583+ }
584+
585+ priceByName := data.
586+ Filter (func (item Itens ) bool {
587+ return item.Qty > 3
588+ }).
589+ GroupSumBy (
590+ func (item Itens ) string { return item.Name },
591+ func (item Itens ) float64 { return item.Price },
592+ )
593+
594+ fmt.Println (priceByName[" Item 4" ]) // 120
595+ ```
596+
597+ Some helpers are also available in chain form.
598+
599+ ``` go
600+ countByName := data.GroupCountBy (func (item Itens ) string {
601+ return item.Name
602+ })
603+
604+ statsByName := data.GroupStatsBy (
605+ func (item Itens ) string { return item.Name },
606+ func (item Itens ) float64 { return item.Price },
607+ )
608+
609+ uniqueByName := data.DistinctBy (func (item Itens ) string {
610+ return item.Name
611+ })
612+
613+ highQty , lowQty := data.Partition (func (item Itens ) bool {
614+ return item.Qty > 3
615+ })
616+
617+ page := data.
618+ SortByFloat64 (func (item Itens ) float64 { return item.Price }).
619+ Skip (10 ).
620+ Take (10 )
621+ ```
0 commit comments