Skip to content

Commit 4b32202

Browse files
committed
utils: add 'Reduce()'
Add a 'Reduce()' function to collapse a given slice into a single accumulator. 'Reduce()' loops over the slice in order and applies the specified reduce function to the slice element and accumulator. Add unit tests applying 'Reduce()' to various slice and accumulator types. Signed-off-by: Victoria Dye <[email protected]>
1 parent 3687877 commit 4b32202

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

internal/utils/slices.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ func Map[T any, S any](in []T, fn func(t T) S) []S {
99
}
1010
return out
1111
}
12+
13+
func Reduce[T any, S any](in []T, acc S, fn func(t T, acc S) S) S {
14+
for _, t := range in {
15+
acc = fn(t, acc)
16+
}
17+
return acc
18+
}

internal/utils/slices_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,58 @@ func TestMap(t *testing.T) {
7979
tt.runTest(t)
8080
}
8181
}
82+
83+
type reduceTest[T any, S any] struct {
84+
title string
85+
86+
// Inputs
87+
in []T
88+
acc S
89+
fn func(T, S) S
90+
91+
// Outputs
92+
expectedOut S
93+
}
94+
95+
var reduceTests = []testable{
96+
reduceTest[int, int]{
97+
title: "int -> int",
98+
99+
in: []int{1, 2, 3},
100+
acc: 0,
101+
fn: func(t int, acc int) int { return acc + t },
102+
103+
expectedOut: 6,
104+
},
105+
reduceTest[string, []string]{
106+
title: "string -> []string",
107+
108+
in: []string{"A", "B", "C"},
109+
acc: []string{"test"},
110+
fn: func(t string, acc []string) []string { return append(acc, t) },
111+
112+
expectedOut: []string{"test", "A", "B", "C"},
113+
},
114+
reduceTest[twoInts, int]{
115+
title: "named struct -> int",
116+
117+
in: []twoInts{{int1: 12, int2: 34}, {int1: 56, int2: 78}},
118+
acc: 0,
119+
fn: func(t twoInts, acc int) int { return acc + t.int1 + t.int2 },
120+
121+
expectedOut: 180,
122+
},
123+
}
124+
125+
func (tt reduceTest[T, S]) runTest(t *testing.T) {
126+
t.Run(tt.title, func(t *testing.T) {
127+
out := utils.Reduce(tt.in, tt.acc, tt.fn)
128+
assert.Equal(t, tt.expectedOut, out)
129+
})
130+
}
131+
132+
func TestReduce(t *testing.T) {
133+
for _, tt := range reduceTests {
134+
tt.runTest(t)
135+
}
136+
}

0 commit comments

Comments
 (0)