Skip to content

Commit 32c7fe9

Browse files
committed
feat: update go version
1 parent e4aec7d commit 32c7fe9

6 files changed

Lines changed: 151 additions & 86 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# gofn
2-
![Coverage](https://img.shields.io/badge/Coverage-88.8%25-brightgreen)
2+
![Coverage](https://img.shields.io/badge/Coverage-87.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
@@ -284,7 +284,7 @@ Fill the array with a value.
284284
```go
285285

286286
a := []int{1, 2, 3, 4, 5}
287-
b := array.Fill(a, 0)
287+
b := array.Fill(a, 0, len(a), 0)
288288

289289
fmt.Println(b) // [0 0 0 0 0]
290290

@@ -392,9 +392,9 @@ data := array.Array[int]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
392392
}).
393393
Map(func(i int) int {
394394
return i * 2
395-
}).
395+
})
396396

397397

398398
fmt.Println(a) // [4 8 12 16 20]
399399

400-
```
400+
```

array/array_test.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package array_test
22

33
import (
44
"fmt"
5-
"github.com/devalexandre/gofn/array"
65
"reflect"
6+
"slices"
77
"testing"
8+
9+
"github.com/devalexandre/gofn/array"
810
)
911

1012
func TestArray(t *testing.T) {
@@ -99,8 +101,16 @@ func TestArray(t *testing.T) {
99101
t.Run("test Shuffle", func(t *testing.T) {
100102
a := array.Array[int]{1, 2, 3, 4, 5}
101103
b := a.Shuffle()
102-
if reflect.DeepEqual(b, array.Array[int]{1, 2, 3, 4, 5}) {
103-
t.Error("Shuffle failed. Got", b, "Expected", array.Array[int]{5, 4, 3, 2, 1})
104+
if len(b) != len(a) {
105+
t.Error("Shuffle failed. Got length", len(b), "Expected", len(a))
106+
}
107+
sorted := slices.Clone(b)
108+
slices.Sort(sorted)
109+
if !reflect.DeepEqual(sorted, a) {
110+
t.Error("Shuffle failed. Got", b, "Expected same elements as", a)
111+
}
112+
if !reflect.DeepEqual(a, array.Array[int]{1, 2, 3, 4, 5}) {
113+
t.Error("Shuffle mutated input. Got", a, "Expected", array.Array[int]{1, 2, 3, 4, 5})
104114
}
105115
})
106116

@@ -151,5 +161,13 @@ func TestArray(t *testing.T) {
151161
if len(grouped) != 4 {
152162
t.Error("GroupBy failed. Got", len(grouped), "Expected", 4)
153163
}
164+
165+
key := "Item 4 - 40"
166+
if len(grouped[key]) != 3 {
167+
t.Error("GroupBy failed. Got", grouped[key], "Expected 3 items")
168+
}
169+
if grouped[key][0].Qty != 10 || grouped[key][1].Qty != 15 || grouped[key][2].Qty != 25 {
170+
t.Error("GroupBy failed. Got", grouped[key], "Expected items in original order")
171+
}
154172
})
155173
}

array/functions.go

Lines changed: 73 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@ package array
22

33
import (
44
"fmt"
5-
"math/rand"
5+
"math/rand/v2"
6+
"slices"
67
"sort"
78
"strings"
8-
"time"
99
)
1010

1111
type Number interface {
12-
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64
12+
~int | ~int8 | ~int16 | ~int32 | ~int64 |
13+
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
14+
~float32 | ~float64
1315
}
1416

1517
func Filter[T any](a []T, f func(T) bool) []T {
16-
y := make([]T, len(a))
17-
i := 0
18+
y := make([]T, 0, len(a))
1819
for _, x := range a {
1920
if f(x) {
20-
y[i] = x
21-
i++
21+
y = append(y, x)
2222
}
2323
}
24-
return y[:i]
24+
return y
2525
}
2626

2727
// with side effects
@@ -54,9 +54,9 @@ func Find[T any](a []T, f func(T) bool) T {
5454
*/
5555

5656
func Map[T, U any](a []T, f func(T) U) []U {
57-
var b = make([]U, len(a))
58-
for i := 0; i < len(a); i++ {
59-
b[i] = f(a[i])
57+
b := make([]U, len(a))
58+
for i, x := range a {
59+
b[i] = f(x)
6060
}
6161

6262
return b
@@ -126,12 +126,7 @@ func Any[T any](input []T, f func(T) bool) bool {
126126
*/
127127

128128
func Some[T any](a []T, f func(T) bool) bool {
129-
for _, x := range a {
130-
if f(x) {
131-
return true
132-
}
133-
}
134-
return false
129+
return Any(a, f)
135130
}
136131

137132
/* Every
@@ -157,7 +152,14 @@ func Every[T any](a []T, f func(T) bool) bool {
157152
*/
158153

159154
func Sum[T Number](a []T) T {
160-
return Reduce(a, func(x, y T) T { return x + y })
155+
if len(a) == 0 {
156+
panic("empty array")
157+
}
158+
total := a[0]
159+
for _, x := range a[1:] {
160+
total += x
161+
}
162+
return total
161163
}
162164

163165
/* Product array of numbers
@@ -167,7 +169,14 @@ func Sum[T Number](a []T) T {
167169
* fmt.Println(b) // 120
168170
*/
169171
func Product[T Number](a []T) T {
170-
return Reduce(a, func(x, y T) T { return x * y })
172+
if len(a) == 0 {
173+
panic("empty array")
174+
}
175+
total := a[0]
176+
for _, x := range a[1:] {
177+
total *= x
178+
}
179+
return total
171180
}
172181

173182
/* Min array of numbers
@@ -177,12 +186,17 @@ func Product[T Number](a []T) T {
177186
* fmt.Println(b) // 1
178187
*/
179188
func Min[T Number](a []T) T {
180-
return Reduce(a, func(x, y T) T {
181-
if x < y {
182-
return x
189+
if len(a) == 0 {
190+
panic("empty array")
191+
}
192+
minimum := a[0]
193+
for _, x := range a[1:] {
194+
if minimum < x {
195+
continue
183196
}
184-
return y
185-
})
197+
minimum = x
198+
}
199+
return minimum
186200
}
187201

188202
/* Max array of numbers
@@ -193,12 +207,17 @@ func Min[T Number](a []T) T {
193207
*/
194208

195209
func Max[T Number](a []T) T {
196-
return Reduce(a, func(x, y T) T {
197-
if x > y {
198-
return x
210+
if len(a) == 0 {
211+
panic("empty array")
212+
}
213+
maximum := a[0]
214+
for _, x := range a[1:] {
215+
if maximum > x {
216+
continue
199217
}
200-
return y
201-
})
218+
maximum = x
219+
}
220+
return maximum
202221
}
203222

204223
/* ForEach
@@ -219,12 +238,7 @@ func ForEach[T any](a []T, f func(T)) {
219238
* fmt.Println(b) // 2
220239
*/
221240
func IndexOf[T comparable](a []T, x T) int {
222-
for i, y := range a {
223-
if x == y {
224-
return i
225-
}
226-
}
227-
return -1
241+
return slices.Index(a, x)
228242
}
229243

230244
/* Contains
@@ -234,7 +248,7 @@ func IndexOf[T comparable](a []T, x T) int {
234248
* fmt.Println(b) // true
235249
*/
236250
func Contains[T comparable](a []T, x T) bool {
237-
return IndexOf(a, x) != -1
251+
return slices.Contains(a, x)
238252
}
239253

240254
/* Equals
@@ -247,15 +261,7 @@ func Contains[T comparable](a []T, x T) bool {
247261
*/
248262

249263
func Equals[T comparable](a, b []T) bool {
250-
if len(a) != len(b) {
251-
return false
252-
}
253-
for i, x := range a {
254-
if x != b[i] {
255-
return false
256-
}
257-
}
258-
return true
264+
return slices.Equal(a, b)
259265
}
260266

261267
/* Reverse
@@ -266,9 +272,8 @@ func Equals[T comparable](a, b []T) bool {
266272
*/
267273
func Reverse[T any](a []T) []T {
268274
b := make([]T, len(a))
269-
for i, x := range a {
270-
b[len(a)-1-i] = x
271-
}
275+
copy(b, a)
276+
slices.Reverse(b)
272277
return b
273278
}
274279

@@ -279,12 +284,11 @@ func Reverse[T any](a []T) []T {
279284
* fmt.Println(b) // [2 5 4 3 1]
280285
*/
281286
func Shuffle[T any](a []T) []T {
282-
r := rand.New(rand.NewSource(time.Now().UnixNano()))
283287
b := make([]T, len(a))
284-
perm := r.Perm(len(a))
285-
for i, j := range perm {
286-
b[i] = a[j]
287-
}
288+
copy(b, a)
289+
rand.Shuffle(len(b), func(i, j int) {
290+
b[i], b[j] = b[j], b[i]
291+
})
288292
return b
289293
}
290294

@@ -297,10 +301,13 @@ func Shuffle[T any](a []T) []T {
297301

298302
func Unique[T comparable](a []T) []T {
299303
b := make([]T, 0, len(a))
304+
seen := make(map[T]struct{}, len(a))
300305
for _, x := range a {
301-
if !Contains(b, x) {
302-
b = append(b, x)
306+
if _, ok := seen[x]; ok {
307+
continue
303308
}
309+
seen[x] = struct{}{}
310+
b = append(b, x)
304311
}
305312
return b
306313
}
@@ -313,8 +320,15 @@ func Unique[T comparable](a []T) []T {
313320
* fmt.Println(c) // [1 2 3 4 5 6 7 8 9 10]
314321
*/
315322

316-
func Union[T comparable](a, b []T) []T {
317-
return append(a, b...)
323+
func Union[T any](a, b []T) []T {
324+
if len(a)+len(b) == 0 {
325+
return append(a, b...)
326+
}
327+
328+
c := make([]T, 0, len(a)+len(b))
329+
c = append(c, a...)
330+
c = append(c, b...)
331+
return c
318332
}
319333

320334
/* Fill
@@ -431,9 +445,8 @@ func Unshift[T any](a []T, x ...T) []T {
431445
func GroupBy[T any, K comparable](w []T, key func(T) K) map[K][]T {
432446
m := make(map[K][]T)
433447
for _, x := range w {
434-
if _, ok := m[key(x)]; !ok {
435-
m[key(x)] = make([]T, 0)
436-
}
448+
k := key(x)
449+
m[k] = append(m[k], x)
437450
}
438451

439452
return m

array/functions_test.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package array_test
22

33
import (
44
"fmt"
5-
"github.com/devalexandre/gofn/array"
65
"reflect"
6+
"slices"
77
"testing"
8+
9+
"github.com/devalexandre/gofn/array"
810
)
911

1012
// test array.Filter
@@ -219,6 +221,15 @@ func TestUnion(t *testing.T) {
219221
}
220222
}
221223

224+
func TestUnionAllowsNonComparableValues(t *testing.T) {
225+
a := []map[string]int{{"a": 1}}
226+
b := []map[string]int{{"b": 2}}
227+
c := array.Union(a, b)
228+
if len(c) != 2 || c[0]["a"] != 1 || c[1]["b"] != 2 {
229+
t.Error("Union failed. Got", c, "Expected two map values")
230+
}
231+
}
232+
222233
// test array.Fill
223234
func TestFill(t *testing.T) {
224235
a := []int{1, 2, 3, 4, 5}
@@ -320,8 +331,16 @@ func TestUnshift(t *testing.T) {
320331
func TestShuffle(t *testing.T) {
321332
a := []int{1, 2, 3, 4, 5}
322333
b := array.Shuffle(a)
323-
if reflect.DeepEqual(a, b) {
324-
t.Error("Shuffle failed. Got", b, "Expected", []int{1, 2, 3, 4, 5})
334+
if len(b) != len(a) {
335+
t.Error("Shuffle failed. Got length", len(b), "Expected", len(a))
336+
}
337+
sorted := slices.Clone(b)
338+
slices.Sort(sorted)
339+
if !reflect.DeepEqual(sorted, a) {
340+
t.Error("Shuffle failed. Got", b, "Expected same elements as", a)
341+
}
342+
if !reflect.DeepEqual(a, []int{1, 2, 3, 4, 5}) {
343+
t.Error("Shuffle mutated input. Got", a, "Expected", []int{1, 2, 3, 4, 5})
325344
}
326345
}
327346

@@ -351,4 +370,12 @@ func TestGroupBy(t *testing.T) {
351370
if len(grouped) != 4 {
352371
t.Error("GroupBy failed. Got", len(grouped), "Expected", 4)
353372
}
373+
374+
key := "Item 4 - 40"
375+
if len(grouped[key]) != 3 {
376+
t.Error("GroupBy failed. Got", grouped[key], "Expected 3 items")
377+
}
378+
if grouped[key][0].Qty != 10 || grouped[key][1].Qty != 15 || grouped[key][2].Qty != 25 {
379+
t.Error("GroupBy failed. Got", grouped[key], "Expected items in original order")
380+
}
354381
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/devalexandre/gofn
22

3-
go 1.18
3+
go 1.24

0 commit comments

Comments
 (0)