diff --git a/_data/version.sh b/_data/version.sh index a6b11b5..785eff6 100755 --- a/_data/version.sh +++ b/_data/version.sh @@ -21,6 +21,11 @@ if [ "$( git rev-parse --abbrev-ref HEAD )" != "master" ]; then exit 1 fi +echo "" +echo -n "Insert optional commit message: " +read commitMessage +echo "" + git pull --ff go get -u ./... @@ -38,13 +43,8 @@ printf "package goext\n\nconst GoextVersion = \"%s\"\n\nconst GoextVersionTimest git add --verbose . -echo -n "Insert option commit message: " - -read commitMessage - msg="v${next_ver}" - if [[ "$commitMessage" != "" ]]; then msg="${msg} ${commitMessage}" fi diff --git a/goextVersion.go b/goextVersion.go index 3113a96..aaf203c 100644 --- a/goextVersion.go +++ b/goextVersion.go @@ -1,5 +1,5 @@ package goext -const GoextVersion = "0.0.183" +const GoextVersion = "0.0.184" -const GoextVersionTimestamp = "2023-07-19T19:24:56+0200" +const GoextVersionTimestamp = "2023-07-19T19:29:59+0200" diff --git a/langext/array.go b/langext/array.go index 5ce22d2..d71536c 100644 --- a/langext/array.go +++ b/langext/array.go @@ -1,6 +1,8 @@ package langext import ( + "errors" + "fmt" "reflect" ) @@ -217,6 +219,15 @@ func ArrFirst[T any](arr []T, comp func(v T) bool) (T, bool) { return *new(T), false } +func ArrFirstOrNil[T any](arr []T, comp func(v T) bool) *T { + for _, v := range arr { + if comp(v) { + return Ptr(v) + } + } + return nil +} + func ArrLast[T any](arr []T, comp func(v T) bool) (T, bool) { found := false result := *new(T) @@ -229,6 +240,22 @@ func ArrLast[T any](arr []T, comp func(v T) bool) (T, bool) { return result, found } +func ArrLastOrNil[T any](arr []T, comp func(v T) bool) *T { + found := false + result := *new(T) + for _, v := range arr { + if comp(v) { + found = true + result = v + } + } + if found { + return Ptr(result) + } else { + return nil + } +} + func ArrFirstIndex[T comparable](arr []T, needle T) int { for i, v := range arr { if v == needle { @@ -265,6 +292,46 @@ func ArrMap[T1 any, T2 any](arr []T1, conv func(v T1) T2) []T2 { return r } +func MapMap[TK comparable, TV any, TR any](inmap map[TK]TV, conv func(k TK, v TV) TR) []TR { + r := make([]TR, 0, len(inmap)) + for k, v := range inmap { + r = append(r, conv(k, v)) + } + return r +} + +func MapMapErr[TK comparable, TV any, TR any](inmap map[TK]TV, conv func(k TK, v TV) (TR, error)) ([]TR, error) { + r := make([]TR, 0, len(inmap)) + for k, v := range inmap { + elem, err := conv(k, v) + if err != nil { + return nil, err + } + r = append(r, elem) + } + return r, nil +} + +func ArrMapExt[T1 any, T2 any](arr []T1, conv func(idx int, v T1) T2) []T2 { + r := make([]T2, len(arr)) + for i, v := range arr { + r[i] = conv(i, v) + } + return r +} + +func ArrMapErr[T1 any, T2 any](arr []T1, conv func(v T1) (T2, error)) ([]T2, error) { + var err error + r := make([]T2, len(arr)) + for i, v := range arr { + r[i], err = conv(v) + if err != nil { + return nil, err + } + } + return r, nil +} + func ArrFilterMap[T1 any, T2 any](arr []T1, filter func(v T1) bool, conv func(v T1) T2) []T2 { r := make([]T2, 0, len(arr)) for _, v := range arr { @@ -275,6 +342,16 @@ func ArrFilterMap[T1 any, T2 any](arr []T1, filter func(v T1) bool, conv func(v return r } +func ArrFilter[T any](arr []T, filter func(v T) bool) []T { + r := make([]T, 0, len(arr)) + for _, v := range arr { + if filter(v) { + r = append(r, v) + } + } + return r +} + func ArrSum[T NumberConstraint](arr []T) T { var r T = 0 for _, v := range arr { @@ -283,6 +360,87 @@ func ArrSum[T NumberConstraint](arr []T) T { return r } +func ArrFlatten[T1 any, T2 any](arr []T1, conv func(v T1) []T2) []T2 { + r := make([]T2, 0, len(arr)) + for _, v1 := range arr { + r = append(r, conv(v1)...) + } + return r +} + +func ArrFlattenDirect[T1 any](arr [][]T1) []T1 { + r := make([]T1, 0, len(arr)) + for _, v1 := range arr { + r = append(r, v1...) + } + return r +} + +func ArrCastToAny[T1 any](arr []T1) []any { + r := make([]any, len(arr)) + for i, v := range arr { + r[i] = any(v) + } + return r +} + +func ArrCastSafe[T1 any, T2 any](arr []T1) []T2 { + r := make([]T2, 0, len(arr)) + for _, v := range arr { + if vcast, ok := any(v).(T2); ok { + r = append(r, vcast) + } + } + return r +} + +func ArrCastErr[T1 any, T2 any](arr []T1) ([]T2, error) { + r := make([]T2, len(arr)) + for i, v := range arr { + if vcast, ok := any(v).(T2); ok { + r[i] = vcast + } else { + return nil, errors.New(fmt.Sprintf("Cannot cast element %d of type %T to type %s", i, v, *new(T2))) + } + } + return r, nil +} + +func ArrCastPanic[T1 any, T2 any](arr []T1) []T2 { + r := make([]T2, len(arr)) + for i, v := range arr { + if vcast, ok := any(v).(T2); ok { + r[i] = vcast + } else { + panic(fmt.Sprintf("Cannot cast element %d of type %T to type %s", i, v, *new(T2))) + } + } + return r +} + +func ArrConcat[T any](arr ...[]T) []T { + c := 0 + for _, v := range arr { + c += len(v) + } + r := make([]T, c) + i := 0 + for _, av := range arr { + for _, v := range av { + r[i] = v + i++ + } + } + return r +} + +// ArrCopy does a shallow copy of the 'in' array +func ArrCopy[T any](in []T) []T { + out := make([]T, len(in)) + copy(out, in) + return out +} + func ArrRemove[T comparable](arr []T, needle T) []T { idx := ArrFirstIndex(arr, needle) if idx >= 0 {