-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New generics for slices #80
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -93,6 +93,16 @@ func Contains[T comparable](tt []T, item T) bool { | |||||||||||||||||||||||||||||||||||||||||||||||||||||
return false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// ContainsAny checks if slice contain element | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
func ContainsAny[T comparable](slice []T, elements ...T) bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
for _, element := range elements { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
if Contains(slice, element) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// InFoldedStringSlice reports whether str is within list(case-insensitive) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
func InFoldedStringSlice(list []string, str string) bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
for _, item := range list { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -201,3 +211,17 @@ func Values[T comparable, N any](tt []T, fn func(T) N) []N { | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ret | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// IsSubset returns if all elements of 'slice' are in 'set' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
func IsSubset[T comparable](slice, subset []T) bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
subsetMap := make(map[T]bool, len(subset)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
for _, v := range subset { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
subsetMap[v] = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
for _, v := range slice { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
if !subsetMap[v] { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+215
to
+227
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This func right now is flipped (checking if
Suggested change
This is also why your tests are failing as the logic is basically flipped. Also even with the above change the last test would fail, however the expected value of Also considering this is working with sets, I'd move it to Lastly, if you'd prefer a bit more readability/reuse over performance, you could simplify it to something like:
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -307,6 +307,51 @@ func TestItemInSlice_String(t *testing.T) { | |
} | ||
} | ||
|
||
func TestContainsAny(t *testing.T) { | ||
tests := []struct { | ||
list []string | ||
find string | ||
find2 string | ||
expected bool | ||
}{ | ||
{[]string{"hello"}, "hello", "world", true}, | ||
{[]string{"hello"}, "hell", "world", false}, | ||
{[]string{"hello", "world", "test"}, "world", "potato", true}, | ||
{[]string{"hello", "world", "test"}, "", "potato", false}, | ||
{[]string{}, "", "", false}, | ||
} | ||
|
||
for i, tc := range tests { | ||
t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { | ||
got := ContainsAny(tc.list, tc.find) | ||
if got != tc.expected { | ||
t.Errorf(diff.Cmp(tc.expected, got)) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestIsSubset(t *testing.T) { | ||
tests := []struct { | ||
set []int | ||
subset []int | ||
expected bool | ||
}{ | ||
{[]int{1, 2, 3, 4}, []int{2, 3}, true}, | ||
{[]int{1, 2, 3, 4}, []int{2, 3, 8}, false}, | ||
{[]int{1, 2, 3, 4}, []int{1, 2, 3, 4}, false}, | ||
Comment on lines
+340
to
+342
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned above, last case should be |
||
} | ||
|
||
for i, tc := range tests { | ||
t.Run(fmt.Sprintf("test-%v", i), func(t *testing.T) { | ||
got := IsSubset(tc.set, tc.subset) | ||
if got != tc.expected { | ||
t.Errorf(diff.Cmp(tc.expected, got)) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestInFoldedStringSlice(t *testing.T) { | ||
tests := []struct { | ||
list []string | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably not necessary as you have
common = slices[0]
below and withcontinue
on first item, it should return immediately after that, albeit it's not bad to have this here 🤔On the other hand it might be worth checking
if len(slices) == 0
and thenreturn nil
as otherwise the line below would panic 😅 Edge case, but if you have somesliceOfSlices = foo()
followed byIntersectionOfMany(sliceOfSlices...)
and the result was empty, you'd get an out of bounds panicThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ripexz, great caught!!!
i've rearranged a little bit, now if there are is no input we will return empty slice, this might be easier to handle when using
IntersectionOfMany()
as it will always return same type. We got this covered in tests withTestIntersectionOfMany():EmptyLists
example