Skip to content

Commit de129d6

Browse files
committed
init
0 parents  commit de129d6

4 files changed

Lines changed: 278 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea/
2+
utils.iml

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/msumera/utils
2+
3+
go 1.23.2

utils.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package utils
2+
3+
func Filter[T any](list []T, fn func(T) bool) []T {
4+
result := make([]T, 0)
5+
for _, t := range list {
6+
if fn(t) {
7+
result = append(result, t)
8+
}
9+
}
10+
return result
11+
}
12+
13+
func FilterNotNil[T any](list []*T) []*T {
14+
result := make([]*T, 0)
15+
for _, t := range list {
16+
if t != nil {
17+
result = append(result, t)
18+
}
19+
}
20+
return result
21+
}
22+
23+
func Map[T, R any](list []T, fn func(T) R) []R {
24+
result := make([]R, 0, len(list))
25+
for _, t := range list {
26+
result = append(result, fn(t))
27+
}
28+
return result
29+
}
30+
31+
func Any[T any](list []T, fn func(T) bool) bool {
32+
for _, t := range list {
33+
if fn(t) {
34+
return true
35+
}
36+
}
37+
return false
38+
}
39+
40+
func ToMap[T any, K comparable](list []T, fn func(T) K) map[K][]T {
41+
result := make(map[K][]T)
42+
for _, t := range list {
43+
k := fn(t)
44+
if _, ok := result[k]; !ok {
45+
result[k] = []T{t}
46+
} else {
47+
result[k] = append(result[k], t)
48+
}
49+
}
50+
return result
51+
}

utils_test.go

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
package utils
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func fnTrue(_ string) bool {
9+
return true
10+
}
11+
12+
func fnLength2(s string) bool {
13+
return len(s) == 2
14+
}
15+
16+
func TestAny(t *testing.T) {
17+
type args[T any] struct {
18+
list []T
19+
fn func(T) bool
20+
}
21+
type testCase[T any] struct {
22+
name string
23+
args args[T]
24+
want bool
25+
}
26+
tests := []testCase[string]{
27+
{
28+
name: "empty",
29+
args: struct {
30+
list []string
31+
fn func(string) bool
32+
}{list: make([]string, 0), fn: fnTrue},
33+
want: false,
34+
},
35+
{
36+
name: "not empty",
37+
args: struct {
38+
list []string
39+
fn func(string) bool
40+
}{list: []string{"xd"}, fn: fnTrue},
41+
want: true,
42+
},
43+
{
44+
name: "not length 2",
45+
args: struct {
46+
list []string
47+
fn func(string) bool
48+
}{list: []string{"xdd"}, fn: fnLength2},
49+
want: false,
50+
},
51+
{
52+
name: "length 2",
53+
args: struct {
54+
list []string
55+
fn func(string) bool
56+
}{list: []string{"xdd", "xd"}, fn: fnLength2},
57+
want: true,
58+
},
59+
}
60+
for _, tt := range tests {
61+
t.Run(tt.name, func(t *testing.T) {
62+
if got := Any(tt.args.list, tt.args.fn); got != tt.want {
63+
t.Errorf("Any() = %v, want %v", got, tt.want)
64+
}
65+
})
66+
}
67+
}
68+
69+
type Obj struct {
70+
Id int
71+
Name string
72+
}
73+
74+
func TestFilter(t *testing.T) {
75+
type args[T any] struct {
76+
list []T
77+
fn func(T) bool
78+
}
79+
type testCase[T any] struct {
80+
name string
81+
args args[T]
82+
want []T
83+
}
84+
tests := []testCase[Obj]{
85+
{
86+
name: "1",
87+
args: struct {
88+
list []Obj
89+
fn func(Obj) bool
90+
}{list: []Obj{
91+
{Id: 1, Name: "a"},
92+
{Id: 2, Name: "b"},
93+
{Id: 3, Name: "c"},
94+
{Id: 4, Name: "d"},
95+
}, fn: func(obj Obj) bool {
96+
return obj.Id == 2 || obj.Name == "c"
97+
}},
98+
want: []Obj{
99+
{Id: 2, Name: "b"},
100+
{Id: 3, Name: "c"},
101+
},
102+
},
103+
}
104+
for _, tt := range tests {
105+
t.Run(tt.name, func(t *testing.T) {
106+
if got := Filter(tt.args.list, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
107+
t.Errorf("Filter() = %v, want %v", got, tt.want)
108+
}
109+
})
110+
}
111+
}
112+
113+
func TestFilterNotNil(t *testing.T) {
114+
type args[T any] struct {
115+
list []T
116+
}
117+
type testCase[T any] struct {
118+
name string
119+
args args[T]
120+
want []T
121+
}
122+
tests := []testCase[*Obj]{
123+
{
124+
name: "1",
125+
args: struct {
126+
list []*Obj
127+
}{list: []*Obj{
128+
nil,
129+
{Id: 1, Name: "a"},
130+
{Id: 2, Name: "b"},
131+
nil,
132+
{Id: 3, Name: "c"},
133+
{Id: 4, Name: "d"},
134+
nil,
135+
}},
136+
want: []*Obj{
137+
{Id: 1, Name: "a"},
138+
{Id: 2, Name: "b"},
139+
{Id: 3, Name: "c"},
140+
{Id: 4, Name: "d"},
141+
},
142+
},
143+
}
144+
for _, tt := range tests {
145+
t.Run(tt.name, func(t *testing.T) {
146+
if got := FilterNotNil(tt.args.list); !reflect.DeepEqual(got, tt.want) {
147+
t.Errorf("Filter() = %v, want %v", got, tt.want)
148+
}
149+
})
150+
}
151+
}
152+
153+
func TestMap(t *testing.T) {
154+
type args[T any, R any] struct {
155+
list []T
156+
fn func(T) R
157+
}
158+
type testCase[T any, R any] struct {
159+
name string
160+
args args[T, R]
161+
want []R
162+
}
163+
tests := []testCase[Obj, string]{
164+
{
165+
name: "1",
166+
args: struct {
167+
list []Obj
168+
fn func(Obj) string
169+
}{list: []Obj{
170+
{Id: 1, Name: "a"},
171+
{Id: 2, Name: "b"},
172+
{Id: 3, Name: "c"},
173+
{Id: 4, Name: "d"},
174+
}, fn: func(obj Obj) string {
175+
return obj.Name
176+
}},
177+
want: []string{"a", "b", "c", "d"},
178+
},
179+
}
180+
for _, tt := range tests {
181+
t.Run(tt.name, func(t *testing.T) {
182+
if got := Map(tt.args.list, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
183+
t.Errorf("Map() = %v, want %v", got, tt.want)
184+
}
185+
})
186+
}
187+
}
188+
189+
func TestToMap(t *testing.T) {
190+
type args[T any, K comparable] struct {
191+
list []T
192+
fn func(T) K
193+
}
194+
type testCase[T any, K comparable] struct {
195+
name string
196+
args args[T, K]
197+
want map[K][]T
198+
}
199+
tests := []testCase[string, int]{
200+
{
201+
name: "length map",
202+
args: args[string, int]{
203+
list: []string{"xd", "xdd", "xddd", "aa"},
204+
fn: func(s string) int {
205+
return len(s)
206+
},
207+
},
208+
want: map[int][]string{
209+
2: {"xd", "aa"},
210+
3: {"xdd"},
211+
4: {"xddd"},
212+
},
213+
},
214+
}
215+
for _, tt := range tests {
216+
t.Run(tt.name, func(t *testing.T) {
217+
if got := ToMap(tt.args.list, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
218+
t.Errorf("ToMap() = %v, want %v", got, tt.want)
219+
}
220+
})
221+
}
222+
}

0 commit comments

Comments
 (0)