Documentation
ΒΆ
Overview ΒΆ
Package gslice provides generic operations for slices.
π‘ HINT: We provide similar functionality for different types in different packages. For example, Clone for copying slice while github.com/bytedance/gg/gmap.Clone for copying map.
- Use github.com/bytedance/gg/gmap for map operations.
- Use github.com/bytedance/gg/gvalue for value operations.
- Use github.com/bytedance/gg/gptr for pointer operations.
- β¦
Operations ΒΆ
High-order functions:
CRUD operations:
Partition operations:
Math operations:
Convert to Map:
Set operations:
Re-order operations:
Type casting/assertion/conversion:
Predicates:
Negative index ΒΆ
Some of operations (such as Get, Insert and Slice) support negative index like Python. The diagram is helpful too for remembering how negative index work:
βββββ¬ββββ¬ββββ¬ββββ¬ββββ¬ββββ
β g β o β l β a β n β g β
βββββ΄ββββ΄ββββ΄ββββ΄ββββ΄ββββ
positive: 0 1 2 3 4 5 (0-based index from start)
negative: -6 -5 -4 -3 -2 -1 (negative index from end)
Example ΒΆ
// High-order function
fmt.Println(Map([]int{1, 2, 3, 4, 5}, strconv.Itoa)) // ["1", "2", "3", "4", "5"]
isEven := func(i int) bool { return i%2 == 0 }
fmt.Println(Filter([]int{1, 2, 3, 4, 5}, isEven)) // [2, 4]
fmt.Println(Reduce([]int{1, 2, 3, 4, 5}, gvalue.Add[int]).Value()) // 15
fmt.Println(Any([]int{1, 2, 3, 4, 5}, isEven)) // true
fmt.Println(All([]int{1, 2, 3, 4, 5}, isEven)) // false
// CRUD operation
fmt.Println(Contains([]int{1, 2, 3, 4, 5}, 2)) // true
fmt.Println(ContainsAny([]int{1, 2, 3, 4, 5}, 2, 6)) // true
fmt.Println(ContainsAll([]int{1, 2, 3, 4, 5}, 2, 6)) // false
fmt.Println(Index([]int{1, 2, 3, 4, 5}, 3).Value()) // 2
fmt.Println(Find([]int{1, 2, 3, 4, 5}, isEven).Value()) // 2
fmt.Println(First([]int{1, 2, 3, 4, 5}).Value()) // 1
fmt.Println(Get([]int{1, 2, 3, 4, 5}, 1).Value()) // 2
fmt.Println(Get([]int{1, 2, 3, 4, 5}, -1).Value()) // 5
// Partion operation
fmt.Println(Range(1, 5)) // [1, 2, 3, 4]
fmt.Println(RangeWithStep(5, 1, -2)) // [5, 3]
fmt.Println(Take([]int{1, 2, 3, 4, 5}, 2)) // [1, 2]
fmt.Println(Take([]int{1, 2, 3, 4, 5}, -2)) // [4, 5]
fmt.Println(Slice([]int{1, 2, 3, 4, 5}, 1, 3)) // [2, 3]
fmt.Println(Chunk([]int{1, 2, 3, 4, 5}, 2)) // [[1, 2] [3, 4] [5]]
fmt.Println(Divide([]int{1, 2, 3, 4, 5}, 2)) // [[1, 2, 3] [4, 5]]
fmt.Println(Concat([]int{1, 2}, []int{3, 4, 5})) // [1, 2, 3, 4, 5]
fmt.Println(Flatten([][]int{{1, 2}, {3, 4, 5}})) // [1, 2, 3, 4, 5]
fmt.Println(Partition([]int{1, 2, 3, 4, 5}, isEven)) // [2, 4], [1, 3, 5]
// Math operation
fmt.Println(Max([]int{1, 2, 3, 4, 5}).Value()) // 5
fmt.Println(Min([]int{1, 2, 3, 4, 5}).Value()) // 1
fmt.Println(MinMax([]int{1, 2, 3, 4, 5}).Value().Values()) // 1 5
fmt.Println(Sum([]int{1, 2, 3, 4, 5})) // 15
// Convert to Map
fmt.Println(gson.ToString(ToMap([]int{1, 2, 3, 4, 5}, func(i int) (string, int) { return strconv.Itoa(i), i }))) // {"1":1,"2":2,"3":3,"4":4,"5":5}
fmt.Println(gson.ToString(ToMapValues([]int{1, 2, 3, 4, 5}, strconv.Itoa))) // {"1":1,"2":2,"3":3,"4":4,"5":5}
fmt.Println(gson.ToString(GroupBy([]int{1, 2, 3, 4, 5}, func(i int) string {
if i%2 == 0 {
return "even"
} else {
return "odd"
}
}))) // {"even":[2,4], "odd":[1,3,5]}
// Set operation
fmt.Println(Union([]int{1, 2, 3}, []int{3, 4, 5})) // [1, 2, 3, 4, 5]
fmt.Println(Intersect([]int{1, 2, 3}, []int{3, 4, 5})) // [3]
fmt.Println(Diff([]int{1, 2, 3}, []int{3, 4, 5})) // [1, 2]
fmt.Println(Uniq([]int{1, 1, 2, 2, 3})) // [1, 2, 3]
fmt.Println(Dup([]int{1, 1, 2, 2, 3})) // [1, 2]
// Re-order operation
s1 := []int{5, 1, 2, 3, 4}
s2, s3, s4 := Clone(s1), Clone(s1), Clone(s1)
Sort(s1)
SortBy(s2, func(i, j int) bool { return i > j })
StableSortBy(s3, func(i, j int) bool { return i > j })
Reverse(s4)
fmt.Println(s1) // [1, 2, 3, 4, 5]
fmt.Println(s2) // [5, 4, 3, 2, 1]
fmt.Println(s3) // [5, 4, 3, 2, 1]
fmt.Println(s4) // [4, 3, 2, 1, 5]
Output: [1 2 3 4 5] [2 4] 15 true false true true false 2 2 1 2 5 [1 2 3 4] [5 3] [1 2] [4 5] [2 3] [[1 2] [3 4] [5]] [[1 2 3] [4 5]] [1 2 3 4 5] [1 2 3 4 5] [2 4] [1 3 5] 5 1 1 5 15 {"1":1,"2":2,"3":3,"4":4,"5":5} {"1":1,"2":2,"3":3,"4":4,"5":5} {"even":[2,4],"odd":[1,3,5]} [1 2 3 4 5] [3] [1 2] [1 2 3] [1 2] [1 2 3 4 5] [5 4 3 2 1] [5 4 3 2 1] [4 3 2 1 5]
Index ΒΆ
- func All[T any](s []T, f func(T) bool) bool
- func Any[T any](s []T, f func(T) bool) bool
- func Avg[T constraints.Number](s []T) float64
- func AvgBy[T any, N constraints.Number](s []T, f func(T) N) float64
- func Chunk[S ~[]T, T any](s S, size int) []S
- func ChunkClone[S ~[]T, T any](s S, size int) []S
- func Clone[S ~[]T, T any](s S) S
- func CloneBy[S ~[]T, T any](s S, f func(T) T) S
- func Compact[S ~[]T, T comparable](s S) S
- func Concat[S ~[]T, T any](ss ...S) S
- func Contains[T comparable](s []T, v T) bool
- func ContainsAll[T comparable](s []T, vs ...T) bool
- func ContainsAny[T comparable](s []T, vs ...T) bool
- func Count[T comparable](s []T, v T) int
- func CountBy[T any](s []T, f func(T) bool) int
- func CountValues[T comparable](s []T) map[T]int
- func CountValuesBy[K comparable, T any](s []T, f func(T) K) map[K]int
- func Diff[S ~[]T, T comparable](s S, againsts ...S) S
- func Divide[S ~[]T, T any](s S, n int) []S
- func DivideClone[S ~[]T, T any](s S, n int) []S
- func Drop[S ~[]T, T any](s S, n int) S
- func DropClone[S ~[]T, T any](s S, n int) S
- func Dup[S ~[]T, T comparable](s S) S
- func DupBy[S ~[]T, K comparable, T any](s S, f func(T) K) S
- func Equal[T comparable](s1, s2 []T) bool
- func EqualBy[T any](s1, s2 []T, eq func(T, T) bool) bool
- func Filter[S ~[]T, T any](s S, f func(T) bool) S
- func FilterMap[F, T any](s []F, f func(F) (T, bool)) []T
- func Find[T any](s []T, f func(T) bool) goption.O[T]
- func FindRev[T any](s []T, f func(T) bool) goption.O[T]
- func First[T any](s []T) goption.O[T]
- func FlatMap[F, T any](s []F, f func(F) []T) []T
- func Flatten[S ~[]T, T any](s []S) S
- func Fold[T1, T2 any](s []T1, f func(T2, T1) T2, init T2) T2
- func ForEach[T any](s []T, f func(v T))
- func ForEachIndexed[T any](s []T, f func(i int, v T))
- func Get[T any, I constraints.Integer](s []T, n I) goption.O[T]
- func GroupBy[S ~[]T, K comparable, T any](s S, f func(T) K) map[K]S
- func Index[T comparable](s []T, e T) goption.O[int]
- func IndexBy[T any](s []T, f func(T) bool) goption.O[int]
- func IndexRev[T comparable](s []T, e T) goption.O[int]
- func IndexRevBy[T any](s []T, f func(T) bool) goption.O[int]
- func Indirect[T any](s []*T) []T
- func IndirectOr[T any](s []*T, fallback T) []T
- func Insert[S ~[]T, T any, I constraints.Integer](s S, pos I, vs ...T) S
- func Intersect[S ~[]T, T comparable](ss ...S) S
- func Last[T any](s []T) goption.O[T]
- func Len[T any](s []T) int
- func Map[F, T any](s []F, f func(F) T) []T
- func Max[T constraints.Ordered](s []T) goption.O[T]
- func MaxBy[T any](s []T, less func(T, T) bool) goption.O[T]
- func Merge[S ~[]T, T any](ss ...S) S
- func Min[T constraints.Ordered](s []T) goption.O[T]
- func MinBy[T any](s []T, less func(T, T) bool) goption.O[T]
- func MinMax[T constraints.Ordered](s []T) goption.O[tuple.T2[T, T]]
- func MinMaxBy[T any](s []T, less func(T, T) bool) goption.O[tuple.T2[T, T]]
- func Of[T any](v ...T) []T
- func Partition[S ~[]T, T any](s S, f func(T) bool) (S, S)
- func PtrOf[T any](s []T) []*T
- func Range[I constraints.Number](start, stop I) []I
- func RangeWithStep[I constraints.Number](start, stop, step I) []I
- func Reduce[T any](s []T, f func(T, T) T) goption.O[T]
- func Reject[S ~[]T, T any](s S, f func(T) bool) S
- func Remove[S ~[]T, T comparable](s S, v T) S
- func RemoveIndex[S ~[]T, I constraints.Integer, T any](s S, index I) S
- func Repeat[T any](v T, n int) []T
- func RepeatBy[T any](fn func() T, n int) []T
- func Reverse[T any](s []T)
- func ReverseClone[S ~[]T, T any](s S) S
- func Shuffle[T any](s []T)
- func ShuffleClone[S ~[]T, T any](s S) S
- func Slice[S ~[]T, I constraints.Integer, T any](s S, start, end I) S
- func SliceClone[S ~[]T, I constraints.Integer, T any](s S, start, end I) S
- func Sort[T constraints.Ordered](s []T)
- func SortBy[T any](s []T, less func(T, T) bool)
- func SortClone[S ~[]T, T constraints.Ordered](s S) S
- func SortCloneBy[S ~[]T, T any](s S, less func(T, T) bool) S
- func StableSortBy[T any](s []T, less func(T, T) bool)
- func Sum[T constraints.Number](s []T) T
- func SumBy[T any, N constraints.Number](s []T, f func(T) N) N
- func Take[S ~[]T, I constraints.Integer, T any](s S, n I) S
- func TakeClone[S ~[]T, I constraints.Integer, T any](s S, n I) S
- func ToMap[T, V any, K comparable](s []T, f func(T) (K, V)) map[K]V
- func ToMapValues[T any, K comparable](s []T, f func(T) K) map[K]T
- func TryFilterMap[F, T any](s []F, f func(F) (T, error)) []T
- func TryMap[F, T any](s []F, f func(F) (T, error)) gresult.R[[]T]
- func TypeAssert[To, From any](s []From) []To
- func Union[S ~[]T, T comparable](ss ...S) S
- func Uniq[S ~[]T, T comparable](s S) S
- func UniqBy[S ~[]T, K comparable, T any](s S, f func(T) K) S
Examples ΒΆ
Constants ΒΆ
This section is empty.
Variables ΒΆ
This section is empty.
Functions ΒΆ
func All ΒΆ
All determines whether all elements of the slice s satisfy the predicate f.
π EXAMPLE:
All([]int{1, 2, 3}, func(x int) bool { return x > 0 }) β© true
func Any ΒΆ
Any determines whether any (at least one) element of the slice s satisfies the predicate f.
Any supports short-circuit evaluation.
π EXAMPLE:
Any([]int{1, 2, 3}, func(x int) bool { return x > 2 }) β© true
π‘ HINT:
func Avg ΒΆ
func Avg[T constraints.Number](s []T) float64
Avg returns the arithmetic mean of the elements of slice s.
π EXAMPLE:
Avg([]int{1, 2, 3, 4, 5}) β© 3.0
Avg([]float64{1, 2, 3, 4, 5}) β© 3.0
π‘ AKA: Mean, Average
func AvgBy ΒΆ
func AvgBy[T any, N constraints.Number](s []T, f func(T) N) float64
AvgBy applies function f to each element of slice s, returns the arithmetic mean of function result.
π‘ AKA: MeanBy, AverageBy
func Chunk ΒΆ
Chunk splits a slice into length-n chunks and returns chunks by a newly allocated slice.
The last chunk will be shorter if n does not evenly divide the length of the list.
π EXAMPLE:
Chunk([]int{0, 1, 2, 3, 4}, 2) β© [][]int{{0, 1}, {2, 3}, {4}}
π‘ HINT:
- If you want to split list into n chunks, use function Divide.
- This function returns sub-slices of original slice, if you modify the sub-slices, the original slice is modified too. Use ChunkClone to prevent this.
- Use Flatten to restore chunks to flat slice.
π‘ AKA: Page, Pagination
func ChunkClone ΒΆ
ChunkClone is variant of function Chunk. It clones the original slice before chunking it.
func Clone ΒΆ
func Clone[S ~[]T, T any](s S) S
Clone returns a shallow copy of the slice. If the given slice is nil, nil is returned.
π EXAMPLE:
Clone([]int{1, 2, 3}) β© []int{1, 2, 3}
Clone([]int{}) β© []int{}
Clone[int](nil) β© nil
π‘ HINT: The elements are copied using assignment (=), so this is a shallow clone. If you want to do a deep clone, use CloneBy with an appropriate element clone function.
π‘ AKA: Copy
func CloneBy ΒΆ
func CloneBy[S ~[]T, T any](s S, f func(T) T) S
CloneBy is variant of Clone, it returns a copy of the slice. Elements are copied using function clone. If the given slice is nil, nil is returned.
π‘ AKA: CopyBy
func Compact ΒΆ
func Compact[S ~[]T, T comparable](s S) S
Compact removes all zero values from given slice s, returns a newly allocated slice.
π EXAMPLE:
Compact([]int{0, 1, 2, 0, 3, 0, 0}) β© []int{1, 2, 3}
Compact([]string{"", "foo", "", "bar"}) β© []string{"foo", "bar"}
π‘ HINT: See github.com/bytedance/gg/gvalue.Zero for details of zero value.
func Concat ΒΆ
func Concat[S ~[]T, T any](ss ...S) S
Concat concatenates slices in order.
π EXAMPLE:
Concat([]int{0}, []int{1, 2}, []int{3, 4}) β© []int{0, 1, 2, 3, 4}
π‘ AKA: Merge, Connect
func Contains ΒΆ
func Contains[T comparable](s []T, v T) bool
Contains returns whether the element occur in slice.
π EXAMPLE:
Contains([]int{0, 1, 2, 3, 4}, 1) β© true
Contains([]int{0, 1, 2, 3, 4}, 5) β© false
Contains([]int{}, 5) β© false
π‘ HINT:
- Use ContainsAll, ContainsAny if you have multiple values to query
- Use Index if you also want to know index of the found value
- Use Any or Find if type of v is non-comparable
func ContainsAll ΒΆ
func ContainsAll[T comparable](s []T, vs ...T) bool
ContainsAll returns whether all of given elements occur in slice.
π EXAMPLE:
s := []int{0, 1, 2, 3, 4}
ContainsAll(s, 0) β© true
ContainsAll(s, 5) β© false
ContainsAll(s, 0, 1) β© true
ContainsAll(s, 0, 5) β© false
func ContainsAny ΒΆ
func ContainsAny[T comparable](s []T, vs ...T) bool
ContainsAny returns whether any of given elements occur in slice.
π EXAMPLE:
s := []int{0, 1, 2, 3, 4}
ContainsAny(s, 0) β© true
ContainsAny(s, 5) β© false
ContainsAny(s, 0, 1) β© true
ContainsAny(s, 0, 5) β© true
func Count ΒΆ
func Count[T comparable](s []T, v T) int
Count returns the times of value v that occur in slice s.
π EXAMPLE:
Count([]string{"a", "b", "c"}, "a") β© 1
Count([]int{0, 1, 2, 0, 5, 3}, 0) β© 2
π‘ HINT:
func CountBy ΒΆ
CountBy returns the times of element in slice s that satisfy the predicate f.
π EXAMPLE:
CountBy([]string{"a", "b", "c"}, func (v string) bool { return v < "b" }) β© 1
CountBy([]int{0, 1, 2, 3, 4}, func (v int) bool { return v % i == 0 }) β© 3
π‘ HINT: Use Any if you just want to know whether at least one element satisfies predicate f.
func CountValues ΒΆ
func CountValues[T comparable](s []T) map[T]int
CountValues returns the occurrences of each element in slice s.
π EXAMPLE:
CountValues([]string{"a", "b", "b"}) β© map[string]int{"a": 1, "b": 2}
CountValues([]int{0, 1, 2, 0, 1, 1}) β© map[int]int{0: 2, 1: 3, 2: 1}
π‘ HINT:
- Use CountValuesBy if the element in slice s is non-comparable
func CountValuesBy ΒΆ
func CountValuesBy[K comparable, T any](s []T, f func(T) K) map[K]int
CountValuesBy returns the times of each element in slice s that satisfy the predicate f.
π EXAMPLE:
CountValuesBy([]int{0, 1, 2, 3, 4}, func(v int) bool { return v%2 == 0 }) β© map[bool]int{true: 3, false: 2}
type Foo struct{ v int }
foos := []Foo{{1}, {2}, {3}}
CountValuesBy(foos, func(v Foo) bool { return v.v%2 == 0 }) β© map[bool]int{true: 1, false: 2}
func Diff ΒΆ
func Diff[S ~[]T, T comparable](s S, againsts ...S) S
Diff returns the difference of slice s against other slices as a newly allocated slice.
π‘ NOTE: If the result is an empty set, always return an empty slice instead of nil
π EXAMPLE:
Diff([]int{1, 2, 3}, []int{3, 4, 5}) β© []int{1, 2}
Diff([]int{1, 2, 3}, []int{4, 5, 6}) β© []int{1, 2, 3}
Diff([]int{1, 2, 3}, []int{1, 2, 3}) β© []int{}
π‘ HINT: if you need a set data structure, use github.com/bytedance/gg/collection/set.
func Divide ΒΆ
Divide splits a list into exactly n slices and returns chunks by a newly allocated slice.
The length of chunks will be different if n does not evenly divide the length of the slice.
π EXAMPLE:
s := []int{0, 1, 2, 3, 4}
Divide(s, 2) β© [][]int{{0, 1, 2}, {3, 4}}
Divide(s, 3) β© [][]int{{0, 1}, {2, 3}, {4}}
Divide([]int{}, 2) β© [][]int{{}, {}}
π‘ HINT:
- If you want to split list into length-n chunks, use Chunk.
- This function returns sub-slices of original slice, if you modify the sub-slices, the original slice is modified too. Use DivideClone to prevent this.
- Use Flatten to restore chunks to flat slice.
π‘ AKA: Page, Pagination
func DivideClone ΒΆ
DivideClone is variant of function Divide. It clones the original slice before dividing it.
func Drop ΒΆ
Drop drops the first n elements of slices s, returns the remaining part of slice, or empty slice if n > len(s).
π EXAMPLE:
s := []int{1, 2, 3, 4, 5}
Drop(s, 0) β© []int{1, 2, 3, 4, 5}
Drop(s, 3) β© []int{4, 5}
Drop(s, 10) β© []int{}
β οΈ WARNING: Panic when n < 0.
π‘ NOTE: This function returns sub-slices of original slice, if you modify the sub-slices, the original slice is modified too. Use DropClone to prevent this.
func Dup ΒΆ
func Dup[S ~[]T, T comparable](s S) S
Dup returns the repeated elements of slice. The result are sorted in order of recurrence.
π EXAMPLE:
Dup([]int{0, 1, 1, 1}) β© []int{1}
Dup([]int{3, 2, 2, 3, 3}) β© []int{2, 3} // in order of recurrence
π‘ HINT:
π‘ AKA: Duplicate.
func DupBy ΒΆ
func DupBy[S ~[]T, K comparable, T any](s S, f func(T) K) S
DupBy returns the repeated elements of slice with key function f. The result is a newly allocated slice contains duplicate elements. The result are sorted in order of recurrence.
π EXAMPLE:
type Foo struct{ Value int }
s := []Foo{{3}, {2}, {2}, {3}, {3}}
DupBy(s, func(v Foo) int { return v.Value }) β© []Foo{{2}, {3}}
π‘ AKA: DuplicateBy.
func Equal ΒΆ
func Equal[T comparable](s1, s2 []T) bool
Equal returns whether two slices are equal.
π EXAMPLE:
Equal([]int{1, 2, 3}, []int{1, 2, 3}) β© true
Equal([]int{1, 2, 3}, []int{1, 2, 3, 4}) β© false
Equal([]int{}, []int{}) β© true
Equal([]int{}, nil) β© true
func EqualBy ΒΆ
EqualBy returns whether two slices are equal by function eq.
π EXAMPLE:
eq := gvalue.Equal[int]
EqualBy([]int{1, 2, 3}, []int{1, 2, 3}, eq) β© true
EqualBy([]int{1, 2, 3}, []int{1, 2, 3, 4}, eq) β© false
EqualBy([]int{}, []int{}, eq) β© true
EqualBy([]int{}, nil, eq) β© true
func Filter ΒΆ
Filter applies predicate f to each element of slice s, returns those elements that satisfy the predicate f as a newly allocated slice.
π EXAMPLE:
Filter([]int{0, 1, 2, 3}, gvalue.IsNotZero[int]) β© []int{1, 2, 3}
π‘ HINT:
func FilterMap ΒΆ
FilterMap does Filter and Map at the same time, applies function f to each element of slice s. f returns (T, bool):
- If true ,the return value with type T will added to the result slice []T.
- If false, the return value with type T will be dropped.
π EXAMPLE:
f := func(i int) (string, bool) { return strconv.Itoa(i), i != 0 }
FilterMap([]int{1, 2, 3, 0, 0}, f) β© []string{"1", "2", "3"}
π‘ HINT: Use TryFilterMap if function f returns (T, error).
func Find ΒΆ
Find returns the possible first element of slice that satisfies predicate f.
π EXAMPLE:
s := []int{0, 1, 2, 3, 4}
Find(s, func(v int) bool { return v > 0 }) β© goption.OK(1)
Find(s, func(v int) bool { return v < 0 }) β© goption.Nil[int]()
π‘ HINT:
- Use Contains if you just want to know whether the value exists
- Use IndexBy if you want to know the index of value
- Use FindRev if you want to find in reverse order
- Use Count if you want to count the occurrences of element
π‘ AKA: Search
func FindRev ΒΆ
FindRev is a variant of Find in reverse order.
π EXAMPLE:
s := []int{0, 1, 2, 3, 4}
FindRev(s, func(v int) bool { return v > 0 }) β© goption.OK(4)
FindRev(s, func(v int) bool { return v < 0 }) β© goption.Nil[int]()
func First ΒΆ
First returns the possible first element of slice s. If the given slice is empty, goption.Nil[T]() is returned.
π EXAMPLE:
First([]int{4, 3, 1, 4}) β© goption.OK(4)
First([]int{}) β© goption.Nil[int]()
π‘ HINT: Use Get to access element at any index.
π‘ AKA: Head
func FlatMap ΒΆ
func FlatMap[F, T any](s []F, f func(F) []T) []T
FlatMap applies function f to each element of slice s with type F. Results of f are flatten and returned as a newly allocated slice with type T.
π EXAMPLE:
type Site struct{ urls []string }
func (s Site) URLs() []string { return s.urls }
sites := []Site{
{[]string{"url1", "url2"}},
{[]string{"url3", "url4"}},
}
FlatMap(sites, Site.URLs) β© []string{"url1", "url2", "url3", "url4"}
π‘ HINT:
func Flatten ΒΆ
func Flatten[S ~[]T, T any](s []S) S
Flatten collapses a tow-dimension slice to one dimension.
π EXAMPLE:
Flatten([][]int{{0}, {1, 2}, {3, 4}}) β© []int{0, 1, 2, 3, 4}
π‘ HINT: Use FlatMap if you want to flatten non-slice elements.
func Fold ΒΆ
func Fold[T1, T2 any](s []T1, f func(T2, T1) T2, init T2) T2
Fold applies function f cumulatively to each element of slice s, so as to fold the slice to a single value. An init element is needed as the initial value of accumulation. If the given slice is empty, the init element is returned.
π EXAMPLE:
s := []int{0, 1, 2, 3}
Fold(s, gvalue.Add[int], 4) β© 10
Fold(s, gvalue.Add[int], 2) β© 8
Fold([]int{}, gvalue.Add[int], 1) β© 1
func ForEach ΒΆ
func ForEach[T any](s []T, f func(v T))
ForEach applies function f to each element of slice s.
π‘ HINT: Use ForEachIndexed If you want to get element with index.
func ForEachIndexed ΒΆ
ForEachIndexed applies function f to each element of slice s. The argument i of function f represents the zero-based index of that element of slice.
func Get ΒΆ
func Get[T any, I constraints.Integer](s []T, n I) goption.O[T]
Get returns the possible element at index n.
[Negative index] is supported. For example:
π EXAMPLE:
s := []int{1, 2, 3, 4}
Get(s, 0) β© goption.OK(1)
Get(s, 1) β© goption.OK(2)
Get(s, -1) β© goption.OK(4)
Get(s, -2) β© goption.OK(3)
π‘ AKA: Nth, At, Access, ByIndex, Load
func GroupBy ΒΆ
func GroupBy[S ~[]T, K comparable, T any](s S, f func(T) K) map[K]S
GroupBy adjacent elements according to key returned by function f.
π EXAMPLE:
GroupBy([]int{1, 2, 3, 4},
func(v int) string {
return gcond.If(v%2 == 0, "even", "odd")
})
β©
map[string][]int{
"odd": {1, 3},
"even": {2, 4},
}
π‘ HINT: If function f returns bool, use Partition instead.
func Index ΒΆ
func Index[T comparable](s []T, e T) goption.O[int]
Index returns the index of the first occurrence of element in slice s, or nil if not present.
π EXAMPLE:
s := []string{"a", "b", "b", "d"}
Index(s, "b") β© goption.OK(1)
Index(s, "e") β© goption.Nil[int]()
π‘ HINT:
func IndexBy ΒΆ
IndexBy is variant of Index, returns the first index of element that satisfying predicate f, or nil if none do.
func IndexRev ΒΆ
func IndexRev[T comparable](s []T, e T) goption.O[int]
IndexRev is a variant of Index in reverse order.
π EXAMPLE:
s := []string{"a", "b", "b", "d"}
IndexRev(s, "b") β© goption.OK(2)
IndexRev(s, "e") β© goption.Nil[int]()
func IndexRevBy ΒΆ
IndexRevBy is variant of IndexRev, returns the first index of element that satisfying predicate f, or nil if none do.
func Indirect ΒΆ
func Indirect[T any](s []*T) []T
Indirect returns the values pointed to by the pointers. If the element is nil, filter it out of the returned slice.
π EXAMPLE:
v1, v2 := 1, 2
Indirect([]*int{ &v1, &v2, nil}) β© []int{1, 2}
π‘ HINT: If you want to replace nil pointer with default value, use IndirectOr.
func IndirectOr ΒΆ
func IndirectOr[T any](s []*T, fallback T) []T
IndirectOr safely dereferences slice of pointers. If the pointer is nil, returns the value fallback instead.
π EXAMPLE:
v1, v2 := 1, 2
IndirectOr([]*int{ &v1, &v2, nil}, -1) β© []int{1, 2, -1}
func Insert ΒΆ
func Insert[S ~[]T, T any, I constraints.Integer](s S, pos I, vs ...T) S
Insert inserts elements vs before position pos, returns a newly allocated slice. [Negative index] is supported.
- Insert(x, 0, ...) inserts at the front of the slice
- Insert(x, len(x), ...) is equivalent to append(x, ...)
- Insert(x, -1, ...) is equivalent to Insert(x, len(x)-1, ...)
π EXAMPLE:
s := []int{0, 1, 2, 3}
Insert(s, 0, 99) β© []int{99, 0, 1, 2, 3}
Insert(s, 0, 98, 99) β© []int{98, 99, 0, 1, 2, 3}
Insert(s, 4, 99) β© []int{0, 1, 2, 3, 99}
Insert(s, 1, 99) β© []int{0, 99, 1, 2, 3}
Insert(s, -1, 99) β© []int{0, 1, 2, 99, 3}
func Intersect ΒΆ
func Intersect[S ~[]T, T comparable](ss ...S) S
Intersect returns the intersection of slices as a newly allocated slice.
π‘ NOTE: If the result is an empty set, always return an empty slice instead of nil
π EXAMPLE:
Intersect([]int{1, 2, 3}, []int{2, 3, 4}) β© []int{2, 3}
Intersect([]int{1, 2, 3}, []int{4, 5, 6}) β© []int{}
Intersect([]int{1, 2, 3}, []int{1, 2, 3}) β© []int{1, 2, 3}
π‘ HINT: if you need a set data structure, use github.com/bytedance/gg/collection/set.
func Last ΒΆ
Last returns the possible last element of slice s. If the given slice is empty, goption.Nil[T]() is returned.
π EXAMPLE:
Last([]int{4, 3, 1, 5}) β© goption.OK(5)
Last([]int{}) β© goption.Nil[int]()
π‘ HINT: Use Get to access element at any index.
π‘ AKA: Tail
func Len ΒΆ
Len returns the length of slice s.
π‘ HINT: This function is designed for high-order function, because the builtin function can not be used as function pointer. For example, if you want to get the total length of a 2D slice:
var s [][]int total1 := SumBy(s, len) // βERRORβ len (built-in) must be called total2 := SumBy(s, Len[int]) // OK
func Map ΒΆ
func Map[F, T any](s []F, f func(F) T) []T
Map applies function f to each element of slice s with type F. Results of f are returned as a newly allocated slice with type T.
π EXAMPLE:
Map([]int{1, 2, 3}, strconv.Itoa) β© []string{"1", "2", "3"}
Map([]int{}, strconv.Itoa) β© []string{}
Map(nil, strconv.Itoa) β© []string{}
π‘ HINT:
func Max ΒΆ
func Max[T constraints.Ordered](s []T) goption.O[T]
Max returns maximum element of slice s. If the given slice is empty, goption.Nil[T]() is returned.
π EXAMPLE:
Max([]int{0, 1, 4, 3, 1, 4}) β© goption.OK(4)
Max([]int{}) β© goption.Nil[int]()
π‘ HINT: If type is not orderable, use MaxBy.
func MaxBy ΒΆ
MaxBy returns the maximum element of slice s determined by function less. If the given slice is empty, goption.Nil[T]() is returned.
π EXAMPLE:
type Foo struct { Value int }
less := func(x, y Foo) bool { return x.Value < y.Value }
s := []Foo{{10}, {1}, {-1}, {100}, {3}}
MaxBy(s, less) β© goption.OK(Foo{100})
func Min ΒΆ
func Min[T constraints.Ordered](s []T) goption.O[T]
Min returns the minimum element of slices s. If the given slice is empty, goption.Nil[T]() is returned.
π EXAMPLE:
Min([]int{1, 4, 3, 1, 4}) β© goption.OK(1)
Min([]int{}) β© goption.Nil[int]()
π‘ HINT: If type is not orderable, use MinBy.
func MinBy ΒΆ
MinBy returns the minimum element of slices s determined by function less. If the given slice is empty, goption.Nil[T]() is returned.
π EXAMPLE:
type Foo struct { Value int }
less := func(x, y Foo) bool { return x.Value < y.Value }
MinBy([]Foo{{10}, {1}, {-1}, {100}, {3}}, less) β© goption.OK(Foo{-1})
func MinMax ΒΆ
MinMax returns both minimum and maximum elements of slice s. If the given slice is empty, goption.Nil[tuple.T2[T, T]]() is returned.
π EXAMPLE:
MinMax([]int{}) β© goption.Nil[int]()
MinMax([]int{1}) β© goption.OK(tuple.T2{1, 1})
MinMax([]int{0, 1, 4, 3, 1, 4}) β© goption.OK(tuple.T2{0, 4})
π‘ HINT: If type is not orderable, use MinMaxBy.
π‘ AKA: Bound
func MinMaxBy ΒΆ
MinMaxBy returns both minimum and maximum elements of slice s. If the given slice is empty, goption.Nil[tuple.T2[T, T]]() is returned.
π EXAMPLE:
type Foo struct { Value int }
less := func(x, y Foo) bool { return x.Value < y.Value }
MinMaxBy([]Foo{{10}, {1}, {-1}, {100}, {3}}, less) β© goption.OK(tuple.T2{Foo{-1}, Foo{100}})
π‘ NOTE: The returned min and max elements may be the same object when each element of the slice is equal
π‘ AKA: BoundBy
func Of ΒΆ
func Of[T any](v ...T) []T
Of creates a slice from variadic arguments. If no argument given, an empty (non-nil) slice []T{} is returned.
π‘ HINT: This function is used to omit verbose types like "[]LooooongTypeName{}" when constructing slices.
π EXAMPLE:
Of(1, 2, 3) β© []int{1, 2, 3}
Of(1) β© []int{1}
Of[int]() β© []int{}
func Partition ΒΆ
Partition applies predicate f to each element of slice s, divides elements into 2 parts: satisfy f and do not satisfy f.
π EXAMPLE:
Partition([]int{0, 1, 2, 3}, gvalue.IsNotZero[int]) β© []int{1, 2, 3}, []int{0}
π‘ HINT:
func PtrOf ΒΆ
func PtrOf[T any](s []T) []*T
PtrOf returns pointers that point to equivalent elements of slice s. ([]T β []*T).
π EXAMPLE:
PtrOf([]int{1, 2, 3}) β© []*int{ (*int)(1), (*int)(2), (*int)(3) },
β οΈ WARNING: The returned pointers do not point to elements of the original slice, user CAN NOT modify the element by modifying the pointer.
func Range ΒΆ
func Range[I constraints.Number](start, stop I) []I
Range is a variant of RangeWithStep, with predefined step 1.
π EXAMPLE:
Range(0, 0) β© []int{}
Range(0, -5) β© []int{}
Range(0, 5) β© []int{0, 1, 2, 3, 4}
func RangeWithStep ΒΆ
func RangeWithStep[I constraints.Number](start, stop, step I) []I
RangeWithStep returns a slice of numbers from start (inclusive) to stop (exclusive) by step. If the interval does not exist, RangeWithStep returns an empty slice. If the step is positive, the returned slice is in ascending order. If the step is negative, the returned slice is in descending order.
π EXAMPLE:
RangeWithStep(0, 0, 2) β© []int{}
RangeWithStep(0, -5, -1) β© []int{0, -1, -2, -3, -4}
RangeWithStep(0, 5, 2) β© []int{0, 2, 4}
RangeWithStep(0, 5, 3) β© []int{0, 3}
RangeWithStep(0.5, 2, 0.5) β© []float64{0.5, 1, 1.5}
func Reduce ΒΆ
Reduce is a variant of Fold, use possible first element of slice as the initial value of accumulation. If the given slice is empty, goption.Nil[T]() is returned.
π EXAMPLE:
Reduce([]int{0, 1, 2, 3}, gvalue.Add[int]) β© goption.OK(6)
Reduce([]int{}, gvalue.Add[int]) β© goption.Nil[int]()
π‘ HINT: Calculate the maximum value is only for example, you can directly use function Max.
func Reject ΒΆ
Reject applies predicate f to each element of slice s, returns those elements that do not satisfy the predicate f as a newly allocated slice.
π EXAMPLE:
Reject([]int{0, 1, 2, 3}, gvalue.IsZero[int]) β© []int{1, 2, 3}
π‘ HINT:
func Remove ΒΆ
func Remove[S ~[]T, T comparable](s S, v T) S
Remove removes all element v from the slice s, returns a newly allocated slice.
π EXAMPLE:
Remove([]int{0, 1, 2, 3, 4}, 3) β© []int{0, 1, 2, 4}
Remove([]int{0, 1, 3, 2, 3, 4}, 3) β© []int{0, 1, 2, 4}
π‘ HINT:
- Use Compact if you just want to remove zero value.
- Use RemoveIndex if you want to remove value by index
π‘ AKA: Delete
func RemoveIndex ΒΆ
func RemoveIndex[S ~[]T, I constraints.Integer, T any](s S, index I) S
RemoveIndex removes the element at index i from slice s and returns a newly allocated slice. If s[i] does not exist or is invalid, this function just clone the original slice. [Negative index] is supported.
- RemoveIndex(x, 0) π° Clone(s[1:])
- RemoveIndex(x, -1) π° Clone(s[0:len(x)-1])
- RemoveIndex(x, len(x)) π° Clone(s)
π EXAMPLE:
RemoveIndex([]int{0, 1, 2, 3, 4}, 3) β© []int{0, 1, 2, 4}
RemoveIndex([]int{0, 1, 2, 3, 4}, -1) β© []int{0, 1, 2, 3}
RemoveIndex([]int{0, 1, 2, 3, 4}, 0) β© []int{1, 2, 3, 4}
RemoveIndex([]int{0, 1, 2, 3, 4}, 100) β© []int{0, 1, 2, 3, 4}
π‘ Hint: This function has O(n) time complexity and ALWAYS returns a newly allocated slice.
π‘ HINT: Use Remove if you want to remove elements by value
π‘ AKA: DeleteIndex
func Repeat ΒΆ
Repeat returns a slice with value v repeating exactly n times. The result is an empty slice if n is 0.
β οΈ WARNING: The function panics if n is negative.
π EXAMPLE:
Repeat(123, -1) β© βPANICβ
Repeat(123, 0) β© []int{}
Repeat(123, 3) β© []int{123, 123, 123}
π‘ HINT: The result slice contains shallow copy of element v. Use RepeatBy with a copier if deep copy is necessary.
func RepeatBy ΒΆ
RepeatBy returns a slice with elements generated by calling fn exactly n times. The result is an empty slice if n is 0.
β οΈ WARNING:
- The function panics if n is negative.
π EXAMPLE:
fn := func() *int { v := 123; return &v }
RepeatBy(fn, -1) β© βPANICβ
RepeatBy(fn, 0) β© []*int{}
RepeatBy(fn, 3) β© []*int{ &int(123), &int(123), &int(123) } // different addresses!
func Reverse ΒΆ
func Reverse[T any](s []T)
Reverse reverses the elements of slices.
π‘ HINT: If you want to reverse in a newly allocated slice, use ReverseClone.
func ReverseClone ΒΆ
func ReverseClone[S ~[]T, T any](s S) S
ReverseClone is variant of Reverse. It clones the original slice before reversing it.
func Shuffle ΒΆ
func Shuffle[T any](s []T)
Shuffle pseudo-randomizes the order of elements.
Shuffle is 2x ~ 40x(parallel) faster than math/rand.Shuffle.
π‘ HINT: If you want to shuffle in a newly allocated slice, use ShuffleClone .
func ShuffleClone ΒΆ
func ShuffleClone[S ~[]T, T any](s S) S
ShuffleClone is variant of Shuffle. It clones the original slice before shuffling it.
func Slice ΒΆ
func Slice[S ~[]T, I constraints.Integer, T any](s S, start, end I) S
Slice returns a sub-slice of the slice S that contains the elements starting from the start-th element up to but not including the end-th element "[start:end)". In other words, it is safer replacement of [Slice Expression].
- Slice(s, 0, 3) π° s[:3]
- Slice(s, 1, 3) π° s[1:3]
[Negative index] is supported:
- Slice(s, -3, -1) π° s[len(s)-3:len(s)-1]
- Slice(s, -3, 0) π° s[len(s)-3:] specially, the 0 at the end implies the end slice.
π EXAMPLE:
s := []int{1, 2, 3, 4, 5}
Slice(s, 0, 3) β© []int{1, 2, 3}
Slice(s, 1, 3) β© []int{2, 3}
Slice(s, 0, 0) β© []int{}
Slice(s, 0, 100) β© []int{1, 2, 3, 4, 5} // won't PANIC even out of range
Slice(s, 100, 99) β© []int{} // won't PANIC even out of range
Slice(s, -3, -1) β© []int{3, 4} // equal to Slice(s, 2, 4) and Slice(s, -3, 4)
Slice(s, -1, 0) β© []int{5} // specially, the 0 at the end implies the end slice
π‘ HINT: This function returns sub-slices of original slice, if you modify the sub-slices, the original slice is modified too. Use SliceClone to prevent this.
func SliceClone ΒΆ
func SliceClone[S ~[]T, I constraints.Integer, T any](s S, start, end I) S
SliceClone is variant of Slice.
func Sort ΒΆ
func Sort[T constraints.Ordered](s []T)
Sort sorts elements of slice in ascending order (from small to large).
π EXAMPLE:
s := []int{1, 3, 2, 4}
Sort(s) β© []int{1, 2, 3, 4}
π‘ HINT:
- Sort in a newly allocated slice, use SortClone
- Sort by a custom comparison function, use SortBy
- Sort in descending order, use SortBy + github.com/bytedance/gg/gvalue.Greater
π‘ AKA: Order
func SortClone ΒΆ
func SortClone[S ~[]T, T constraints.Ordered](s S) S
SortClone is variant of Sort. It clones the original slice before sorting it.
func SortCloneBy ΒΆ
SortCloneBy is variant of function SortBy. It clones the original slice before sorting it.
func StableSortBy ΒΆ
StableSortBy is variant of SortBy, it keeps the original order of equal elements when sorting.
func Sum ΒΆ
func Sum[T constraints.Number](s []T) T
Sum returns the arithmetic sum of the elements of slice s.
π EXAMPLE:
Sum([]int{1, 2, 3, 4, 5}) β© 15
Sum([]float64{1, 2, 3, 4, 5}) β© 15.0
β οΈ WARNING: The returned type is still T, it may overflow for smaller types (such as int8, uint8).
func SumBy ΒΆ
func SumBy[T any, N constraints.Number](s []T, f func(T) N) N
SumBy applies function f to each element of slice s, returns the arithmetic sum of function result.
func Take ΒΆ
func Take[S ~[]T, I constraints.Integer, T any](s S, n I) S
Take returns the first n elements of slices s if 0 <= n <= len(s), or slice itself if n > len(s). If -len(s) <= n < 0, returns the last -n elements of slice s, or slice itself if n < -len(s).
π EXAMPLE:
s := []int{1, 2, 3, 4, 5}
Take(s, 0) β© []int{}
Take(s, 3) β© []int{1, 2, 3}
Take(s, 10) β© []int{1, 2, 3, 4, 5}
Take(s, -1) β© []int{5}
Take(s, -3) β© []int{3, 4, 5}
Take(s, -10) β© []int{1, 2, 3, 4, 5}
π‘ HINT: This function returns sub-slices of original slice, if you modify the sub-slices, the original slice is modified too. Use TakeClone to prevent this.
func TakeClone ΒΆ
func TakeClone[S ~[]T, I constraints.Integer, T any](s S, n I) S
TakeClone is variant of Take.
func ToMap ΒΆ
func ToMap[T, V any, K comparable](s []T, f func(T) (K, V)) map[K]V
ToMap collects elements of slice to map, both map keys and values are produced by mapping function f.
π EXAMPLE:
type Foo struct {
ID int
Name string
}
mapper := func(f Foo) (int, string) { return f.ID, f.Name }
ToMap([]Foo{}, mapper) β© map[int]string{}
s := []Foo{{1, "one"}, {2, "two"}, {3, "three"}}
ToMap(s, mapper) β© map[int]string{1: "one", 2: "two", 3: "three"}
func ToMapValues ΒΆ
func ToMapValues[T any, K comparable](s []T, f func(T) K) map[K]T
ToMapValues collects elements of slice to values of map, the map keys are produced by mapping function f.
π EXAMPLE:
type Foo struct {
ID int
}
id := func(f Foo) int { return f.ID }
ToMapValues([]Foo{}, id) β© map[int]Foo{}
ToMapValues([]Foo{ {1}, {2}, {1}, {3}}, id) β© map[int]Foo{1: {1}, 2: {2}, 3: {3}}
π‘ AKA: Kotlin's associateBy
func TryFilterMap ΒΆ
TryFilterMap is a variant of FilterMap that allows function f to fail (return error).
π EXAMPLE:
TryFilterMap([]string{"1", "2", "3"}, strconv.Atoi) β© []int{1, 2, 3}
TryFilterMap([]string{"1", "2", "a"}, strconv.Atoi) β© []int{1, 2}
func TryMap ΒΆ
TryMap is a variant of Map that allows function f to fail (return error).
π EXAMPLE:
TryMap([]string{"1", "2", "3"}, strconv.Atoi) β© gresult.OK([]int{1, 2, 3})
TryMap([]string{"1", "2", "a"}, strconv.Atoi) β© gresult.Err("strconv.Atoi: parsing \"a\": invalid syntax")
TryMap([]string{}, strconv.Atoi) β© gresult.OK([]int{})
π‘ HINT: Use TryFilterMap if you want to ignore error during mapping.
func TypeAssert ΒΆ
func TypeAssert[To, From any](s []From) []To
TypeAssert converts a slice from type From to type To by type assertion.
π EXAMPLE:
TypeAssert[int]([]any{1, 2, 3, 4}) β© []int{1, 2, 3, 4}
TypeAssert[any]([]int{1, 2, 3, 4}) β© []any{1, 2, 3, 4}
TypeAssert[int64]([]int{1, 2, 3, 4}) β© βPANICβ
β οΈ WARNING:
- This function may βPANICβ. See github.com/bytedance/gg/gvalue.TypeAssert for more details
func Union ΒΆ
func Union[S ~[]T, T comparable](ss ...S) S
Union returns the unions of slices as a newly allocated slices.
π‘ NOTE: If the result is an empty set, always return an empty slice instead of nil
π EXAMPLE:
Union([]int{1, 2, 3}, []int{3, 4, 5}) β© []int{1, 2, 3, 4, 5}
Union([]int{1, 2, 3}, []int{}) β© []int{1, 2, 3}
Union([]int{}, []int{3, 4, 5}) β© []int{3, 4, 5}
π‘ HINT: if you need a set data structure, use github.com/bytedance/gg/collection/set.
func Uniq ΒΆ
func Uniq[S ~[]T, T comparable](s S) S
Uniq returns the distinct elements of slice. Elements are ordered by their first occurrence.
π EXAMPLE:
Uniq([]int{0, 1, 4, 3, 1, 4}) β© []int{0, 1, 4, 3}
π‘ HINT:
π‘ AKA: Distinct, Dedup, Unique
func UniqBy ΒΆ
func UniqBy[S ~[]T, K comparable, T any](s S, f func(T) K) S
UniqBy returns the distinct elements of slice with key function f. The result is a newly allocated slice without duplicate elements.
π EXAMPLE:
type Foo struct{ Value int }
s := []Foo{{0}, {1}, {4}, {3}, {1}, {4}}
UniqBy(s, func(v Foo) int { return v.Value }) β© []Foo{{0}, {1}, {4}, {3}}
π‘ AKA: DistinctBy, DedupBy.
Types ΒΆ
This section is empty.