-
-
Notifications
You must be signed in to change notification settings - Fork 823
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
209 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package mutable | ||
|
||
import "math/rand" | ||
|
||
// Filter iterates over elements of collection, returning an array of all elements predicate returns truthy for. | ||
// The function returns the modified slice, which may be shorter than the original if some elements were removed. | ||
// The order of elements in the original slice is preserved in the output. | ||
// Play: | ||
func Filter[T any](collection *[]T, predicate func(item T) bool) { | ||
FilterI(collection, func(item T, index int) bool { | ||
return predicate(item) | ||
}) | ||
} | ||
|
||
// Filter iterates over elements of collection, returning an array of all elements predicate returns truthy for. | ||
// The function returns the modified slice, which may be shorter than the original if some elements were removed. | ||
// The order of elements in the original slice is preserved in the output. | ||
// Play: | ||
func FilterI[T any](collection *[]T, predicate func(item T, index int) bool) { | ||
j := 0 | ||
for i := range *collection { | ||
if predicate((*collection)[i], i) { | ||
(*collection)[j] = (*collection)[i] | ||
j++ | ||
} | ||
} | ||
|
||
*collection = (*collection)[:j] | ||
} | ||
|
||
// Uniq returns a duplicate-free version of an array, in which only the first occurrence of each element is kept. | ||
// The order of result values is determined by the order they occur in the array. | ||
// Play: | ||
func Uniq[T comparable](collection *[]T) { | ||
size := len(*collection) | ||
seen := make(map[T]struct{}, size) | ||
j := 0 | ||
|
||
for i := 0; i < size; i++ { | ||
if _, ok := seen[(*collection)[i]]; ok { | ||
continue | ||
} | ||
|
||
seen[(*collection)[i]] = struct{}{} | ||
|
||
(*collection)[j] = (*collection)[i] | ||
j++ | ||
} | ||
|
||
*collection = (*collection)[:j] | ||
} | ||
|
||
// UniqBy returns a duplicate-free version of an array, in which only the first occurrence of each element is kept. | ||
// The order of result values is determined by the order they occur in the array. It accepts `iteratee` which is | ||
// invoked for each element in array to generate the criterion by which uniqueness is computed. | ||
// Play: | ||
func UniqBy[T any, U comparable](collection *[]T, iteratee func(item T) U) { | ||
size := len(*collection) | ||
seen := make(map[U]struct{}, size) | ||
j := 0 | ||
|
||
for i := 0; i < size; i++ { | ||
key := iteratee((*collection)[i]) | ||
if _, ok := seen[key]; ok { | ||
continue | ||
} | ||
|
||
seen[key] = struct{}{} | ||
|
||
(*collection)[j] = (*collection)[i] | ||
j++ | ||
} | ||
|
||
*collection = (*collection)[:j] | ||
} | ||
|
||
// Shuffle returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm. | ||
// Play: | ||
func Shuffle[T any](collection []T) { | ||
rand.Shuffle(len(collection), func(i, j int) { | ||
collection[i], collection[j] = collection[j], collection[i] | ||
}) | ||
} | ||
|
||
// Reverse reverses array so that the first element becomes the last, the second element becomes the second to last, and so on. | ||
// Play: | ||
func Reverse[T any](collection []T) { | ||
length := len(collection) | ||
half := length / 2 | ||
|
||
for i := 0; i < half; i = i + 1 { | ||
j := length - 1 - i | ||
collection[i], collection[j] = collection[j], collection[i] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package mutable | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestFilter(t *testing.T) { | ||
t.Parallel() | ||
is := assert.New(t) | ||
|
||
r1 := []int{1, 2, 3, 4} | ||
Filter(&r1, func(x int) bool { | ||
return x%2 == 0 | ||
}) | ||
is.Equal([]int{2, 4}, r1) | ||
|
||
r2 := []string{"", "foo", "", "bar", ""} | ||
Filter(&r2, func(x string) bool { | ||
return len(x) > 0 | ||
}) | ||
is.Equal([]string{"foo", "bar"}, r2) | ||
} | ||
|
||
func TestFilterI(t *testing.T) { | ||
t.Parallel() | ||
is := assert.New(t) | ||
|
||
r1 := []int{1, 2, 3, 4} | ||
FilterI(&r1, func(x int, _ int) bool { | ||
return x%2 == 0 | ||
}) | ||
is.Equal([]int{2, 4}, r1) | ||
|
||
r2 := []string{"", "foo", "", "bar", ""} | ||
FilterI(&r2, func(x string, _ int) bool { | ||
return len(x) > 0 | ||
}) | ||
is.Equal([]string{"foo", "bar"}, r2) | ||
} | ||
|
||
func TestUniq(t *testing.T) { | ||
t.Parallel() | ||
is := assert.New(t) | ||
|
||
result1 := []int{1, 2, 2, 1} | ||
Uniq(&result1) | ||
is.Equal(len(result1), 2) | ||
is.Equal(result1, []int{1, 2}) | ||
} | ||
|
||
func TestUniqBy(t *testing.T) { | ||
t.Parallel() | ||
is := assert.New(t) | ||
|
||
result1 := []int{0, 1, 2, 3, 4, 5} | ||
UniqBy(&result1, func(i int) int { | ||
return i % 3 | ||
}) | ||
|
||
is.Equal(len(result1), 3) | ||
is.Equal(result1, []int{0, 1, 2}) | ||
} | ||
|
||
func TestShuffle(t *testing.T) { | ||
t.Parallel() | ||
is := assert.New(t) | ||
|
||
result1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} | ||
Shuffle(result1) | ||
is.NotEqual(result1, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) | ||
|
||
result2 := []int{} | ||
Shuffle(result2) | ||
is.Equal(result2, []int{}) | ||
} | ||
|
||
func TestReverse(t *testing.T) { | ||
t.Parallel() | ||
is := assert.New(t) | ||
|
||
result1 := []int{0, 1, 2, 3, 4, 5} | ||
Reverse(result1) | ||
is.Equal(result1, []int{5, 4, 3, 2, 1, 0}) | ||
|
||
result2 := []int{0, 1, 2, 3, 4, 5, 6} | ||
Reverse(result2) | ||
is.Equal(result2, []int{6, 5, 4, 3, 2, 1, 0}) | ||
|
||
result3 := []int{} | ||
Reverse(result3) | ||
is.Equal(result3, []int{}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters