mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-15 10:12:29 +08:00
Compare commits
5 Commits
bf332b9f1c
...
089fd4e13c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
089fd4e13c | ||
|
|
6c40e02324 | ||
|
|
a270b1b634 | ||
|
|
260fb795d3 | ||
|
|
8c036f830c |
141
slice/slice.go
141
slice/slice.go
@@ -36,7 +36,7 @@ func ContainSubSlice[T comparable](slice, subslice []T) bool {
|
||||
|
||||
// Chunk creates an slice of elements split into groups the length of size.
|
||||
func Chunk[T any](slice []T, size int) [][]T {
|
||||
var result [][]T
|
||||
result := [][]T{}
|
||||
|
||||
if len(slice) == 0 || size <= 0 {
|
||||
return result
|
||||
@@ -95,7 +95,8 @@ func Concat[T any](slice []T, values ...[]T) []T {
|
||||
|
||||
// Difference creates an slice of whose element in slice but not in comparedSlice
|
||||
func Difference[T comparable](slice, comparedSlice []T) []T {
|
||||
var result []T
|
||||
result := []T{}
|
||||
|
||||
for _, v := range slice {
|
||||
if !Contain(comparedSlice, v) {
|
||||
result = append(result, v)
|
||||
@@ -123,7 +124,7 @@ func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(inde
|
||||
}
|
||||
|
||||
//DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice. The comparator is invoked with two arguments: (arrVal, othVal).
|
||||
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T {
|
||||
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value1, value2 T) bool) []T {
|
||||
result := make([]T, 0)
|
||||
|
||||
getIndex := func(arr []T, item T, comparison func(v1, v2 T) bool) int {
|
||||
@@ -180,11 +181,8 @@ func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) boo
|
||||
|
||||
// Every return true if all of the values in the slice pass the predicate function.
|
||||
func Every[T any](slice []T, predicate func(index int, item T) bool) bool {
|
||||
if predicate == nil {
|
||||
panic("predicate func is missing")
|
||||
}
|
||||
|
||||
var currentLength int
|
||||
|
||||
for i, v := range slice {
|
||||
if predicate(i, v) {
|
||||
currentLength++
|
||||
@@ -196,9 +194,6 @@ func Every[T any](slice []T, predicate func(index int, item T) bool) bool {
|
||||
|
||||
// None return true if all the values in the slice mismatch the criteria
|
||||
func None[T any](slice []T, predicate func(index int, item T) bool) bool {
|
||||
if predicate == nil {
|
||||
panic("predicate func is missing")
|
||||
}
|
||||
|
||||
var currentLength int
|
||||
for i, v := range slice {
|
||||
@@ -212,39 +207,30 @@ func None[T any](slice []T, predicate func(index int, item T) bool) bool {
|
||||
|
||||
// Some return true if any of the values in the list pass the predicate function.
|
||||
func Some[T any](slice []T, predicate func(index int, item T) bool) bool {
|
||||
if predicate == nil {
|
||||
panic("predicate func is missing")
|
||||
}
|
||||
|
||||
for i, v := range slice {
|
||||
if predicate(i, v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Filter iterates over elements of slice, returning an slice of all elements pass the predicate function
|
||||
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T {
|
||||
if predicate == nil {
|
||||
panic("predicate func is missing")
|
||||
}
|
||||
|
||||
result := make([]T, 0)
|
||||
for i, v := range slice {
|
||||
if predicate(i, v) {
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Count iterates over elements of slice, returns a count of all matched elements
|
||||
func Count[T any](slice []T, predicate func(index int, item T) bool) int {
|
||||
if predicate == nil {
|
||||
panic("predicate func is missing")
|
||||
}
|
||||
|
||||
if len(slice) == 0 {
|
||||
return 0
|
||||
}
|
||||
@@ -261,10 +247,6 @@ func Count[T any](slice []T, predicate func(index int, item T) bool) int {
|
||||
|
||||
// GroupBy iterate over elements of the slice, each element will be group by criteria, returns two slices
|
||||
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T) {
|
||||
if groupFn == nil {
|
||||
panic("groupFn func is missing")
|
||||
}
|
||||
|
||||
if len(slice) == 0 {
|
||||
return make([]T, 0), make([]T, 0)
|
||||
}
|
||||
@@ -285,11 +267,7 @@ func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
|
||||
}
|
||||
|
||||
// GroupWith return a map composed of keys generated from the resultults of running each element of slice thru iteratee.
|
||||
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T {
|
||||
if iteratee == nil {
|
||||
panic("iteratee func is missing")
|
||||
}
|
||||
|
||||
func GroupWith[T any, U comparable](slice []T, iteratee func(item T) U) map[U][]T {
|
||||
result := make(map[U][]T)
|
||||
|
||||
for _, v := range slice {
|
||||
@@ -306,10 +284,6 @@ func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T {
|
||||
// Find iterates over elements of slice, returning the first one that passes a truth test on predicate function.
|
||||
// If return T is nil then no items matched the predicate func
|
||||
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) {
|
||||
if predicate == nil {
|
||||
panic("predicate func is missing")
|
||||
}
|
||||
|
||||
if len(slice) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
@@ -332,10 +306,6 @@ func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) {
|
||||
// FindLast iterates over elements of slice from end to begin, returning the first one that passes a truth test on predicate function.
|
||||
// If return T is nil then no items matched the predicate func
|
||||
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) {
|
||||
if predicate == nil {
|
||||
panic("predicate func is missing")
|
||||
}
|
||||
|
||||
if len(slice) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
@@ -408,10 +378,6 @@ func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value {
|
||||
|
||||
// ForEach iterates over elements of slice and invokes function for each element
|
||||
func ForEach[T any](slice []T, iteratee func(index int, item T)) {
|
||||
if iteratee == nil {
|
||||
panic("iteratee func is missing")
|
||||
}
|
||||
|
||||
for i, v := range slice {
|
||||
iteratee(i, v)
|
||||
}
|
||||
@@ -419,10 +385,6 @@ func ForEach[T any](slice []T, iteratee func(index int, item T)) {
|
||||
|
||||
// Map creates an slice of values by running each element of slice thru iteratee function.
|
||||
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U {
|
||||
if iteratee == nil {
|
||||
panic("iteratee func is missing")
|
||||
}
|
||||
|
||||
result := make([]U, len(slice), cap(slice))
|
||||
for i, v := range slice {
|
||||
result[i] = iteratee(i, v)
|
||||
@@ -433,9 +395,6 @@ func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U {
|
||||
|
||||
// Reduce creates an slice of values by running each element of slice thru iteratee function.
|
||||
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T {
|
||||
if iteratee == nil {
|
||||
panic("iteratee func is missing")
|
||||
}
|
||||
|
||||
if len(slice) == 0 {
|
||||
return initial
|
||||
@@ -604,12 +563,8 @@ func UpdateAt[T any](slice []T, index int, value T) []T {
|
||||
|
||||
// Unique remove duplicate elements in slice.
|
||||
func Unique[T comparable](slice []T) []T {
|
||||
if len(slice) == 0 {
|
||||
return []T{}
|
||||
}
|
||||
result := []T{}
|
||||
|
||||
// here no use map filter. if use it, the result slice element order is random, not same as origin slice
|
||||
var result []T
|
||||
for i := 0; i < len(slice); i++ {
|
||||
v := slice[i]
|
||||
skip := true
|
||||
@@ -629,11 +584,8 @@ func Unique[T comparable](slice []T) []T {
|
||||
|
||||
// UniqueBy call iteratee func with every item of slice, then remove duplicated.
|
||||
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T {
|
||||
if len(slice) == 0 {
|
||||
return []T{}
|
||||
}
|
||||
result := []T{}
|
||||
|
||||
var result []T
|
||||
for _, v := range slice {
|
||||
val := iteratee(v)
|
||||
result = append(result, val)
|
||||
@@ -642,20 +594,39 @@ func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T {
|
||||
return Unique(result)
|
||||
}
|
||||
|
||||
// Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
|
||||
// Union creates a slice of unique values, in order, from all given slices.
|
||||
func Union[T comparable](slices ...[]T) []T {
|
||||
if len(slices) == 0 {
|
||||
return []T{}
|
||||
}
|
||||
|
||||
// append all slices, then unique it
|
||||
var allElements []T
|
||||
result := []T{}
|
||||
contain := map[T]struct{}{}
|
||||
|
||||
for _, slice := range slices {
|
||||
allElements = append(allElements, slice...)
|
||||
for _, item := range slice {
|
||||
if _, ok := contain[item]; !ok {
|
||||
contain[item] = struct{}{}
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Unique(allElements)
|
||||
return result
|
||||
}
|
||||
|
||||
// UnionBy is like Union, what's more it accepts iteratee which is invoked for each element of each slice
|
||||
func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T {
|
||||
result := []T{}
|
||||
contain := map[V]struct{}{}
|
||||
|
||||
for _, slice := range slices {
|
||||
for _, item := range slice {
|
||||
val := predicate(item)
|
||||
if _, ok := contain[val]; !ok {
|
||||
contain[val] = struct{}{}
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection creates a slice of unique values that included by all slices.
|
||||
@@ -667,8 +638,6 @@ func Intersection[T comparable](slices ...[]T) []T {
|
||||
return Unique(slices[0])
|
||||
}
|
||||
|
||||
var result []T
|
||||
|
||||
reducer := func(sliceA, sliceB []T) []T {
|
||||
hashMap := make(map[T]int)
|
||||
for _, val := range sliceA {
|
||||
@@ -685,7 +654,7 @@ func Intersection[T comparable](slices ...[]T) []T {
|
||||
return out
|
||||
}
|
||||
|
||||
result = reducer(slices[0], slices[1])
|
||||
result := reducer(slices[0], slices[1])
|
||||
|
||||
reduceSlice := make([][]T, 2)
|
||||
for i := 2; i < len(slices); i++ {
|
||||
@@ -818,14 +787,14 @@ func Without[T comparable](slice []T, values ...T) []T {
|
||||
return slice
|
||||
}
|
||||
|
||||
out := make([]T, 0, len(slice))
|
||||
result := make([]T, 0, len(slice))
|
||||
for _, v := range slice {
|
||||
if !Contain(values, v) {
|
||||
out = append(out, v)
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
return result
|
||||
}
|
||||
|
||||
// IndexOf returns the index at which the first occurrence of a value is found in a slice or return -1
|
||||
@@ -854,18 +823,20 @@ func LastIndexOf[T comparable](slice []T, value T) int {
|
||||
|
||||
// ToSlicePointer returns a pointer to the slices of a variable parameter transformation
|
||||
func ToSlicePointer[T any](value ...T) []*T {
|
||||
out := make([]*T, len(value))
|
||||
result := make([]*T, len(value))
|
||||
for i := range value {
|
||||
out[i] = &value[i]
|
||||
result[i] = &value[i]
|
||||
}
|
||||
return out
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ToSlice returns a slices of a variable parameter transformation
|
||||
func ToSlice[T any](value ...T) []T {
|
||||
out := make([]T, len(value))
|
||||
copy(out, value)
|
||||
return out
|
||||
result := make([]T, len(value))
|
||||
copy(result, value)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// AppendIfAbsent only absent append the value
|
||||
@@ -875,3 +846,15 @@ func AppendIfAbsent[T comparable](slice []T, value T) []T {
|
||||
}
|
||||
return slice
|
||||
}
|
||||
|
||||
// KeyBy converts a slice to a map based on a callback function
|
||||
func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T {
|
||||
result := make(map[U]T, len(slice))
|
||||
|
||||
for _, v := range slice {
|
||||
k := iteratee(v)
|
||||
result[k] = v
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -428,6 +428,17 @@ func TestUnion(t *testing.T) {
|
||||
assert.Equal([]int{1, 3, 4, 6}, Union(s1))
|
||||
}
|
||||
|
||||
func TestUnionBy(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestUnionBy")
|
||||
|
||||
testFunc := func(i int) int {
|
||||
return i / 2
|
||||
}
|
||||
|
||||
result := UnionBy(testFunc, []int{0, 1, 2, 3, 4, 5}, []int{0, 2, 10})
|
||||
assert.Equal(result, []int{0, 2, 4, 10})
|
||||
}
|
||||
|
||||
func TestIntersection(t *testing.T) {
|
||||
s1 := []int{1, 2, 2, 3}
|
||||
s2 := []int{1, 2, 3, 4}
|
||||
@@ -644,3 +655,13 @@ func TestReplaceAll(t *testing.T) {
|
||||
assert.Equal([]string{"x", "b", "x", "c", "d", "x"}, ReplaceAll(strs, "a", "x"))
|
||||
assert.Equal([]string{"a", "b", "a", "c", "d", "a"}, ReplaceAll(strs, "e", "x"))
|
||||
}
|
||||
|
||||
func TestKeyBy(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestKeyBy")
|
||||
|
||||
result := KeyBy([]string{"a", "ab", "abc"}, func(str string) int {
|
||||
return len(str)
|
||||
})
|
||||
|
||||
assert.Equal(result, map[int]string{1: "a", 2: "ab", 3: "abc"})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user