feat: add slice and file helpers (#62)

This commit is contained in:
Robert Kaussow 2024-03-11 11:57:11 +01:00 committed by GitHub
parent 937c247354
commit 7930845038
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 158 additions and 0 deletions

View File

@ -1,7 +1,9 @@
package file
import (
"fmt"
"os"
"path/filepath"
)
// The MSDN docs appear to say that a normal path that is 248 bytes long will work;
@ -42,3 +44,24 @@ func DeleteDir(path string) error {
return os.Remove(path)
}
// ExpandFileList takes a list of file globs and expands them into a list
// of matching file paths. It returns the expanded file list and any errors
// from glob matching. This allows safely passing user input globs through to
// glob matching.
func ExpandFileList(fileList []string) ([]string, error) {
var result []string
for _, glob := range fileList {
globbed, err := filepath.Glob(glob)
if err != nil {
return result, fmt.Errorf("failed to match %s: %w", glob, err)
}
if globbed != nil {
result = append(result, globbed...)
}
}
return result, nil
}

44
slice/slice.go Normal file
View File

@ -0,0 +1,44 @@
package slice
// SetDifference returns a slice containing the elements in slice a that are not in slice b.
func SetDifference[T comparable](a, b []T, unique bool) []T {
result := make([]T, 0)
if unique {
a = Unique(a)
}
for _, aItem := range a {
found := false
for _, bItem := range b {
if aItem == bItem {
found = true
break
}
}
if !found {
result = append(result, aItem)
}
}
return result
}
// Unique returns a slice containing only the unique elements of the given slice.
func Unique[T comparable](s []T) []T {
seen := make(map[T]struct{})
result := make([]T, 0)
for _, v := range s {
if _, ok := seen[v]; !ok {
seen[v] = struct{}{}
result = append(result, v)
}
}
return result
}

91
slice/slice_test.go Normal file
View File

@ -0,0 +1,91 @@
package slice
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSetDifference(t *testing.T) {
tests := []struct {
name string
a []string
b []string
expected []string
unique bool
}{
{
name: "both empty",
a: []string{},
b: []string{},
expected: []string{},
unique: false,
},
{
name: "remove common element",
a: []string{"a", "b", "c"},
b: []string{"b"},
expected: []string{"a", "c"},
unique: false,
},
{
name: "remove a and c",
a: []string{"a", "b", "c"},
b: []string{"a", "c"},
expected: []string{"b"},
unique: false,
},
{
name: "no common elements",
a: []string{"a", "b", "c"},
b: []string{"d", "e"},
expected: []string{"a", "b", "c"},
unique: false,
},
{
name: "remove duplicates",
a: []string{"a", "a", "b"},
b: []string{"b"},
expected: []string{"a"},
unique: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := SetDifference(tt.a, tt.b, tt.unique)
assert.Equal(t, tt.expected, result)
})
}
}
func TestUnique(t *testing.T) {
tests := []struct {
name string
input []int
want []int
}{
{
name: "empty slice",
input: []int{},
want: []int{},
},
{
name: "single value",
input: []int{1},
want: []int{1},
},
{
name: "duplicates",
input: []int{1, 2, 3, 2},
want: []int{1, 2, 3},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Unique(tt.input)
assert.Equal(t, tt.want, got)
})
}
}