AI docs
This commit is contained in:
@@ -11,10 +11,15 @@ import (
|
||||
// ints, and other types not implementing []any can be worked with.
|
||||
// For example, this is useful if you need to work on the output of regexs.
|
||||
|
||||
// list creates a new list (slice) containing the provided arguments.
|
||||
// It accepts any number of arguments of any type and returns them as a slice.
|
||||
func list(v ...any) []any {
|
||||
return v
|
||||
}
|
||||
|
||||
// push appends an element to the end of a list (slice or array).
|
||||
// It takes a list and a value, and returns a new list with the value appended.
|
||||
// This function will panic if the first argument is not a slice or array.
|
||||
func push(list any, v any) []any {
|
||||
l, err := mustPush(list, v)
|
||||
if err != nil {
|
||||
@@ -23,99 +28,103 @@ func push(list any, v any) []any {
|
||||
return l
|
||||
}
|
||||
|
||||
// mustPush is the implementation of push that returns an error instead of panicking.
|
||||
// It converts the input list to a slice of any type, then appends the value.
|
||||
func mustPush(list any, v any) ([]any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
nl := make([]any, l)
|
||||
for i := 0; i < l; i++ {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return append(nl, v), nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot push on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// prepend adds an element to the beginning of a list (slice or array).
|
||||
// It takes a list and a value, and returns a new list with the value at the start.
|
||||
// This function will panic if the first argument is not a slice or array.
|
||||
func prepend(list any, v any) []any {
|
||||
l, err := mustPrepend(list, v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// mustPrepend is the implementation of prepend that returns an error instead of panicking.
|
||||
// It converts the input list to a slice of any type, then prepends the value.
|
||||
func mustPrepend(list any, v any) ([]any, error) {
|
||||
//return append([]any{v}, list...)
|
||||
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
nl := make([]any, l)
|
||||
for i := 0; i < l; i++ {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return append([]any{v}, nl...), nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot prepend on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// chunk divides a list into sub-lists of the specified size.
|
||||
// It takes a size and a list, and returns a list of lists, each containing
|
||||
// up to 'size' elements from the original list.
|
||||
// This function will panic if the second argument is not a slice or array.
|
||||
func chunk(size int, list any) [][]any {
|
||||
l, err := mustChunk(size, list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// mustChunk is the implementation of chunk that returns an error instead of panicking.
|
||||
// It divides the input list into chunks of the specified size.
|
||||
func mustChunk(size int, list any) ([][]any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
|
||||
cs := int(math.Floor(float64(l-1)/float64(size)) + 1)
|
||||
nl := make([][]any, cs)
|
||||
|
||||
for i := 0; i < cs; i++ {
|
||||
numChunks := int(math.Floor(float64(l-1)/float64(size)) + 1)
|
||||
if numChunks > sliceSizeLimit {
|
||||
return nil, fmt.Errorf("number of chunks %d exceeds maximum limit of %d", numChunks, sliceSizeLimit)
|
||||
}
|
||||
result := make([][]any, numChunks)
|
||||
for i := 0; i < numChunks; i++ {
|
||||
clen := size
|
||||
if i == cs-1 {
|
||||
// Handle the last chunk which might be smaller
|
||||
if i == numChunks-1 {
|
||||
clen = int(math.Floor(math.Mod(float64(l), float64(size))))
|
||||
if clen == 0 {
|
||||
clen = size
|
||||
}
|
||||
}
|
||||
|
||||
nl[i] = make([]any, clen)
|
||||
|
||||
result[i] = make([]any, clen)
|
||||
for j := 0; j < clen; j++ {
|
||||
ix := i*size + j
|
||||
nl[i][j] = l2.Index(ix).Interface()
|
||||
result[i][j] = l2.Index(ix).Interface()
|
||||
}
|
||||
}
|
||||
|
||||
return nl, nil
|
||||
return result, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot chunk type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// last returns the last element of a list (slice or array).
|
||||
// If the list is empty, it returns nil.
|
||||
// This function will panic if the argument is not a slice or array.
|
||||
func last(list any) any {
|
||||
l, err := mustLast(list)
|
||||
if err != nil {
|
||||
@@ -125,6 +134,8 @@ func last(list any) any {
|
||||
return l
|
||||
}
|
||||
|
||||
// mustLast is the implementation of last that returns an error instead of panicking.
|
||||
// It returns the last element of the list or nil if the list is empty.
|
||||
func mustLast(list any) (any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
@@ -142,6 +153,9 @@ func mustLast(list any) (any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// first returns the first element of a list (slice or array).
|
||||
// If the list is empty, it returns nil.
|
||||
// This function will panic if the argument is not a slice or array.
|
||||
func first(list any) any {
|
||||
l, err := mustFirst(list)
|
||||
if err != nil {
|
||||
@@ -151,6 +165,8 @@ func first(list any) any {
|
||||
return l
|
||||
}
|
||||
|
||||
// mustFirst is the implementation of first that returns an error instead of panicking.
|
||||
// It returns the first element of the list or nil if the list is empty.
|
||||
func mustFirst(list any) (any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
@@ -168,6 +184,9 @@ func mustFirst(list any) (any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// rest returns all elements of a list except the first one.
|
||||
// If the list is empty, it returns nil.
|
||||
// This function will panic if the argument is not a slice or array.
|
||||
func rest(list any) []any {
|
||||
l, err := mustRest(list)
|
||||
if err != nil {
|
||||
@@ -177,28 +196,30 @@ func rest(list any) []any {
|
||||
return l
|
||||
}
|
||||
|
||||
// mustRest is the implementation of rest that returns an error instead of panicking.
|
||||
// It returns all elements of the list except the first one, or nil if the list is empty.
|
||||
func mustRest(list any) ([]any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
nl := make([]any, l-1)
|
||||
for i := 1; i < l; i++ {
|
||||
nl[i-1] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return nl, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot find rest on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// initial returns all elements of a list except the last one.
|
||||
// If the list is empty, it returns nil.
|
||||
// This function will panic if the argument is not a slice or array.
|
||||
func initial(list any) []any {
|
||||
l, err := mustInitial(list)
|
||||
if err != nil {
|
||||
@@ -208,28 +229,30 @@ func initial(list any) []any {
|
||||
return l
|
||||
}
|
||||
|
||||
// mustInitial is the implementation of initial that returns an error instead of panicking.
|
||||
// It returns all elements of the list except the last one, or nil if the list is empty.
|
||||
func mustInitial(list any) ([]any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
nl := make([]any, l-1)
|
||||
for i := 0; i < l-1; i++ {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return nl, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot find initial on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// sortAlpha sorts a list of strings alphabetically.
|
||||
// If the input is not a slice or array, it returns a single-element slice
|
||||
// containing the string representation of the input.
|
||||
func sortAlpha(list any) []string {
|
||||
k := reflect.Indirect(reflect.ValueOf(list)).Kind()
|
||||
switch k {
|
||||
@@ -242,6 +265,8 @@ func sortAlpha(list any) []string {
|
||||
return []string{strval(list)}
|
||||
}
|
||||
|
||||
// reverse returns a new list with the elements in reverse order.
|
||||
// This function will panic if the argument is not a slice or array.
|
||||
func reverse(v any) []any {
|
||||
l, err := mustReverse(v)
|
||||
if err != nil {
|
||||
@@ -251,42 +276,45 @@ func reverse(v any) []any {
|
||||
return l
|
||||
}
|
||||
|
||||
// mustReverse is the implementation of reverse that returns an error instead of panicking.
|
||||
// It returns a new list with the elements in reverse order.
|
||||
func mustReverse(v any) ([]any, error) {
|
||||
tp := reflect.TypeOf(v).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(v)
|
||||
|
||||
l := l2.Len()
|
||||
// We do not sort in place because the incoming array should not be altered.
|
||||
nl := make([]any, l)
|
||||
for i := 0; i < l; i++ {
|
||||
nl[l-i-1] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return nl, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot find reverse on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// compact returns a new list with all "empty" elements removed.
|
||||
// An element is considered empty if it's nil, zero, an empty string, or an empty collection.
|
||||
// This function will panic if the argument is not a slice or array.
|
||||
func compact(list any) []any {
|
||||
l, err := mustCompact(list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// mustCompact is the implementation of compact that returns an error instead of panicking.
|
||||
// It returns a new list with all "empty" elements removed.
|
||||
func mustCompact(list any) ([]any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
nl := []any{}
|
||||
var nl []any
|
||||
var item any
|
||||
for i := 0; i < l; i++ {
|
||||
item = l2.Index(i).Interface()
|
||||
@@ -294,30 +322,32 @@ func mustCompact(list any) ([]any, error) {
|
||||
nl = append(nl, item)
|
||||
}
|
||||
}
|
||||
|
||||
return nl, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot compact on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// uniq returns a new list with duplicate elements removed.
|
||||
// The first occurrence of each element is kept.
|
||||
// This function will panic if the argument is not a slice or array.
|
||||
func uniq(list any) []any {
|
||||
l, err := mustUniq(list)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// mustUniq is the implementation of uniq that returns an error instead of panicking.
|
||||
// It returns a new list with duplicate elements removed.
|
||||
func mustUniq(list any) ([]any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
dest := []any{}
|
||||
var dest []any
|
||||
var item any
|
||||
for i := 0; i < l; i++ {
|
||||
item = l2.Index(i).Interface()
|
||||
@@ -325,13 +355,15 @@ func mustUniq(list any) ([]any, error) {
|
||||
dest = append(dest, item)
|
||||
}
|
||||
}
|
||||
|
||||
return dest, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot find uniq on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// inList checks if a value is present in a list.
|
||||
// It uses deep equality comparison to check for matches.
|
||||
// Returns true if the value is found, false otherwise.
|
||||
func inList(haystack []any, needle any) bool {
|
||||
for _, h := range haystack {
|
||||
if reflect.DeepEqual(needle, h) {
|
||||
@@ -341,21 +373,23 @@ func inList(haystack []any, needle any) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// without returns a new list with all occurrences of the specified values removed.
|
||||
// This function will panic if the first argument is not a slice or array.
|
||||
func without(list any, omit ...any) []any {
|
||||
l, err := mustWithout(list, omit...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// mustWithout is the implementation of without that returns an error instead of panicking.
|
||||
// It returns a new list with all occurrences of the specified values removed.
|
||||
func mustWithout(list any, omit ...any) ([]any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
res := []any{}
|
||||
var item any
|
||||
@@ -365,22 +399,25 @@ func mustWithout(list any, omit ...any) ([]any, error) {
|
||||
res = append(res, item)
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot find without on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// has checks if a value is present in a list.
|
||||
// Returns true if the value is found, false otherwise.
|
||||
// This function will panic if the second argument is not a slice or array.
|
||||
func has(needle any, haystack any) bool {
|
||||
l, err := mustHas(needle, haystack)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// mustHas is the implementation of has that returns an error instead of panicking.
|
||||
// It checks if a value is present in a list.
|
||||
func mustHas(needle any, haystack any) (bool, error) {
|
||||
if haystack == nil {
|
||||
return false, nil
|
||||
@@ -397,38 +434,41 @@ func mustHas(needle any, haystack any) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
default:
|
||||
return false, fmt.Errorf("cannot find has on type %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// slice extracts a portion of a list based on the provided indices.
|
||||
// Usage examples:
|
||||
// $list := [1, 2, 3, 4, 5]
|
||||
// slice $list -> list[0:5] = list[:]
|
||||
// slice $list 0 3 -> list[0:3] = list[:3]
|
||||
// slice $list 3 5 -> list[3:5]
|
||||
// slice $list 3 -> list[3:5] = list[3:]
|
||||
//
|
||||
// This function will panic if the first argument is not a slice or array.
|
||||
func slice(list any, indices ...any) any {
|
||||
l, err := mustSlice(list, indices...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// mustSlice is the implementation of slice that returns an error instead of panicking.
|
||||
// It extracts a portion of a list based on the provided indices.
|
||||
func mustSlice(list any, indices ...any) (any, error) {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Determine start and end indices
|
||||
var start, end int
|
||||
if len(indices) > 0 {
|
||||
start = toInt(indices[0])
|
||||
@@ -438,13 +478,15 @@ func mustSlice(list any, indices ...any) (any, error) {
|
||||
} else {
|
||||
end = toInt(indices[1])
|
||||
}
|
||||
|
||||
return l2.Slice(start, end).Interface(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("list should be type of slice or array but %s", tp)
|
||||
}
|
||||
}
|
||||
|
||||
// concat combines multiple lists into a single list.
|
||||
// It takes any number of lists and returns a new list containing all elements.
|
||||
// This function will panic if any argument is not a slice or array.
|
||||
func concat(lists ...any) any {
|
||||
var res []any
|
||||
for _, list := range lists {
|
||||
|
||||
Reference in New Issue
Block a user