g

package module
v1.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2024 License: MIT Imports: 12 Imported by: 6

README

Go Report Card License License Stay with Ukraine

G

The g package is a comprehensive utility library for Go that provides a rich collection of generic helper functions to streamline common programming tasks. Built with modern Go features, particularly generics, this package offers efficient, reliable, and easy-to-use solutions for everyday development challenges.

Installation

To install the package, use go get:

go get github.com/goloop/g

Note: This package requires Go 1.20 or later due to its extensive use of generics.

Why This Package?

Ternary Operator Alternative

In languages like C++ and Python, you can write concise conditional expressions:

// C++
int max = (a > b) ? a : b;

// Python
max = a if a > b else b

Go doesn't have a ternary operator, leading to verbose code:

max := a
if a < b {
    max = b
}

With the g package, you can write:

max := g.If(a > b, a, b)
Efficient List Operations

Python makes checking if an element is in a slice easy:

if a in some_slice:
    # do something

The g package provides an efficient concurrent implementation:

if g.In(a, someSlice...) {
    // do something
}

Key Features

Type Conversion & Validation
  • String to various types (bool, int, float)
  • Type checking and verification
  • Safe numeric conversions with overflow protection
// String to int conversion with default value
num, err := g.StringToInt("123", 0)

// Safe sum with overflow protection
sum, err := g.SafeSum(1, math.MaxInt64)
Mathematical Operations
  • Basic arithmetic with overflow protection
  • Statistical functions (Average, Median)
  • Random number generation
  • Number properties (Even, Odd, Whole)
avg := g.Average(1, 2, 3, 4, 5)
median := g.Median(1, 2, 3, 4, 5)
random := g.Random(1, 10)
Collection Operations
  • Set operations (Union, Intersection, Difference)
  • List manipulation (Sort, Shuffle, Reverse)
  • Functional programming helpers (Map, Filter, Reduce)
unique := g.Union(slice1, slice2)
g.Sort(numbers)
doubled := g.Map(numbers, func(n int) int { return n * 2 })
String Processing
  • Character filtering and preservation
  • String cleaning and normalization
  • Pattern-based manipulation
// Remove unwanted characters
cleaned := g.Weed("Hello\t World\n")

// Keep only specific characters
numbers := g.Preserve("+1-234-567-8900", g.Numbers)
Date & Time
  • Flexible date parsing
  • Time zone manipulation
  • Python-style date formatting
date, err := g.StringToDate("2023-12-01")
newTime, err := g.ChangeTimeZone(time.Now(), "America/New_York")
Excel-like Functions
  • HLOOKUP/VLOOKUP implementations
  • Range operations
  • Value ranking
rank := g.Rank(7, []float64{1, 5, 2, 3, 7, 8})
value := g.HLookup("key", lookupSlice, resultSlice, defaultValue)

Complete Function List

View the complete function documentation

Here are some key function categories:

Basic Operations
  • If - Ternary operator alternative
  • In - Check if element exists in slice
  • All/Any - Check conditions across values
  • IsEmpty/IsWhole/IsEven/IsOdd - Value validation
Mathematical
  • Min/Max - Find extremes
  • Sum/SafeSum - Addition with optional overflow protection
  • Average/Median - Statistical calculations
  • Random/RandomList - Random value generation
Collection Operations
  • Union/Intersection/Difference/SymmetricDifference - Set operations
  • Sort/Shuffle/Reverse - List manipulation
  • Map/Filter/Reduce - Functional programming
  • Zip/CartesianProduct - List combinations
String Operations
  • StringToInt/StringToFloat/StringToBool - String parsing
  • Weed/Preserve/Trim - String cleaning
  • IntToString/FloatToString/BoolToString - Value formatting
Date & Time
  • StringToDate/DateToString - Date parsing and formatting
  • ChangeTimeZone/SetTimeZone/MoveTimeZone - Time zone operations
Excel-like Functions
  • HLookup/VLookup - Value lookups
  • Rank - Value ranking
  • Range/Rangef - Range generation

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License

Documentation

Overview

Package g is a comprehensive utility library for Go 1.20+ that provides a rich set of generic, type-safe helper functions to streamline common programming tasks. Built with modern Go features, particularly generics, this package offers efficient, reliable, and easy-to-use solutions for everyday development challenges.

Core Features

Type Conversion & Handling:

  • String-to-X conversions (bool, int, float)
  • X-to-String conversions (bool, int, float)
  • Pointer creation and conditional pointer handling
  • Type checking and verification utilities

Date & Time Management:

  • Flexible date parsing with multiple format support
  • Python-style date formatting compatibility
  • Time zone manipulation and conversion
  • Date-to-string formatting with various templates

Collection Operations:

  • Functional programming helpers (Map, Filter, Reduce)
  • Set operations (Union, Intersection, Difference)
  • List manipulation (Sort, Shuffle, Reverse)
  • Array searching and filtering
  • Element ranking and lookup

Mathematical Operations:

  • Basic arithmetic with overflow protection
  • Statistical functions (Average, Median)
  • Random number generation
  • Range generation with custom steps
  • Number property checking (Even, Odd, Whole)

String Processing:

  • Character filtering and preservation
  • String cleaning and normalization
  • Pattern-based string manipulation
  • Whitespace and special character handling

Logical Operations:

  • Conditional evaluation (If)
  • Value presence checking (Any, All)
  • Zero-value detection
  • Type-specific comparisons

Excel-like Functions:

  • HLOOKUP/VLOOKUP implementations
  • Range operations
  • Value ranking

Key Types and Interfaces

The package provides several key types and interfaces:

  • Numerable: Interface for numeric types
  • Verifiable: Interface for comparable types
  • Pair: Generic struct for paired values

Performance Features

The package implements various performance optimizations:

  • Concurrent processing for large datasets
  • Efficient memory management
  • Optimized algorithms for common operations
  • Thread-safe implementations where necessary

Example Usage

Type conversion:

num, err := g.StringToInt("123")
str := g.IntToString(456)

Date handling:

date, err := g.StringToDate("2023-12-01")
formatted, err := g.DateToString(date, "2006-01-02")

Collection operations:

numbers := []int{3, 1, 4, 1, 5}
g.Sort(numbers)
unique := g.Distinct(numbers)

Mathematical operations:

avg := g.Average(1, 2, 3, 4, 5)
random := g.Random(1, 10)

String processing:

cleaned := g.Weed("Hello\t World\n")
preserved := g.Preserve("+1-234-567-8900", g.Numbers)

Logical operations:

result := g.If(condition, trueVal, falseVal)
exists := g.Any(slice...)

Focus and Design Principles

The package is designed with emphasis on:

  • Type safety through generics
  • Consistent and intuitive API design
  • Comprehensive error handling
  • Efficient performance
  • Developer-friendly documentation
  • Practical utility in real-world applications

This library serves as a robust foundation for Go applications, providing tested, efficient implementations of commonly needed functionality while maintaining type safety and performance.

Index

Constants

View Source
const (
	// Numbers is a string of all numbers.
	Numbers = "1234567890"

	// Letters is a string of all ASCII letters.
	Letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

	// Symbols is a string of all special ASCII symbols.
	Symbols = ".,:;!?/\\|`~@#$%^&*()_+-=<>"

	// Quotes is a string of all quotes.
	Quotes = "'\"`"

	// Brackets is a string of all breakers.
	Brackets = "()[]<>{}"

	// Whitespaces is a set of characters that are used as whitespaces.
	Whitespaces = " \t\b"

	// Breakers is a set of characters that are used as breakers.
	Breakers = "\n\r\v\f"

	// Hidden contains part of Whitespaces group and all Breakers.
	Hidden = "\t\b\n\r\v\f"
)
View Source
const MaxRangeSize = 100_000_000

MaxRangeSize is the maximum size for range generation by the Range function.

Variables

This section is empty.

Functions

func Abs

func Abs[T Numerable](v T) T

Abs returns the absolute value of a numeric input value.

The function takes a value of a type that satisfies the Numerable interface and returns its absolute value as the same type.

For numeric types that support the negation operator (-), the function uses the negation operator to calculate the absolute value. For unsigned integer types, the absolute value is equal to the original value.

Example usage:

var n int = -10
fmt.Println(g.Abs(n))  // Output: 10

var f float64 = -15.5
fmt.Println(g.Abs(f))  // Output: 15.5

var u uint = 20
fmt.Println(g.Abs(u))  // Output: 20

func All

func All[T any](v ...T) bool

All returns true if all values in the provided slice are not zero values for their types.

If at least one value is a zero value, it immediately returns false. If the slice is empty, it returns false.

This function is generic and can work with any type T.

Example usage:

allNonZero := g.All(1, 2, 3)
fmt.Println(allNonZero) // Output: true

someZero := g.All(1, 0, 3)
fmt.Println(someZero) // Output: false

allNonZeroMixed := g.All(1, "a", true)
fmt.Println(allNonZeroMixed) // Output: true

empty := g.All()
fmt.Println(empty) // Output: false

Warning: the function checks the list as the whole object, that is:

l := []bool{false, false, false}
g.All(l)    // Returns: true, because list is not an empty
            // and not an empty list is true
g.All(l...) // Returns: false, because not all elements
            // of the list are true

func AllList added in v1.10.0

func AllList[T any](v []T) bool

AllList is a synonym for the All function that accepts a set of elements as a slice.

This function prevents accidentally passing a slice as a value (whole object).

func Any

func Any[T any](v ...T) bool

Any returns true if at least one value in the provided slice is not a zero value for its type.

As soon as it finds a value that is not a zero value, it returns true. If all values in the slice are zero values or the slice is empty, it returns false.

Example usage:

// Check if any element in a slice of integers is non-zero.
ints := []int{0, 0, 0, 1, 0}
resultI := g.Any(ints...)
fmt.Println(resultI) // Output: true

// Check if any element in a slice of strings is non-empty.
strings := []string{"", "hello", "", ""}
resultS := g.Any(strings...)
fmt.Println(resultS) // Output: true

// Check if any element in a slice of booleans is true.
bools := []bool{false, false, true, false}
resultB := g.Any(bools...)
fmt.Println(resultB) // Output: true

Warning: the function checks the list as the whole object, that is:

l := []bool{false, false, false}
g.Any(l)    // Returns: true, because list is not an empty
            // and not an empty list is true
g.Any(l...) // Returns: false, because not all elements
            // of the list are true

func AnyList added in v1.10.0

func AnyList[T any](v []T) bool

AnyList is a synonym for the Any function that accepts a set of elements as a slice.

This function prevents accidentally passing a slice as a value (whole object).

func Average

func Average[T Numerable](v ...T) float64

If no values are provided, it returns 0. Note: this function returns the average as a float64, regardless of the input type.

Example usage:

values := []int{3, 5, 7, 1, 9, 2}
avg := g.Average(values...)
fmt.Println(avg)  // Output: 4.5

floats := []float64{1.1, 2.2, 3.3}
avg = g.Average(floats...)
fmt.Println(avg)  // Output: 2.2

func BoolToString added in v1.13.0

func BoolToString(b bool) string

BoolToString converts a boolean to a string. It returns "true" for true and "false" for false.

Example Usage:

s := BoolToString(true) // "true"
s := BoolToString(false) // "false"

func CartesianProduct

func CartesianProduct[T any](a []T, b []T) [][2]T

CartesianProduct returns all possible pairs from two slices.

The function generates a slice of pairs, where each pair consists of an element from the first input slice and an element from the second input slice. The length of the returned slice is equal to the product of the lengths of the input slices.

This function is generic and can work with any type T.

Note: This function does not preserve the order of elements. The order of elements in the returned slice can be different from the order of elements in the input slices.

Example usage:

a := []int{1, 2}
b := []int{3, 4}
result := g.CartesianProduct(a, b)
// Output: [[1, 3], [1, 4], [2, 3], [2, 4]]

x := []string{"A", "B"}
y := []string{"C", "D"}
result := g.CartesianProduct(x, y)
// Output: [["A", "C"], ["A", "D"], ["B", "C"], ["B", "D"]]

func ChangeTimeZone added in v1.7.0

func ChangeTimeZone(t time.Time, timezone string) (time.Time, error)

ChangeTimeZone returns a time where the hour and minute are the same as the input time, but the time zone is changed. This can be used to convert a local time to a different time zone while keeping the "clock time" the same.

Example usage:

t, _ := time.Parse(time.RFC3339, "2023-06-17T08:15:45Z")
newTime, err := ChangeTimeZone(t, "America/New_York")
if err != nil {
    log.Fatal(err)
}
fmt.Println(newTime)
// Output: 2023-06-17 08:15:45 -0400 EDT

func Complement

func Complement[T comparable](a []T, b []T) []T

Complement takes a universal set (b) and a subset of it (a) and Output: a new slice containing items present in the universal set but not in the subset. The type T must be comparable.

The function returns the complement of the subset.

The function is generic and can work with any type T that is comparable.

Note: This function does not preserve the order of elements. The order of elements in the returned slice can be different from the order of elements in the input slices.

Example usage:

u := []int{1, 2, 3, 4, 5}
a := []int{1, 2, 3}
result := g.Complement(a, u)
fmt.Println(result) // Output: [4, 5]

u := []string{"a", "b", "c", "d", "e"}
a := []string{"a", "b", "c"}
result := g.Complement(a, u)
fmt.Println(result) // Output: ["d", "e"]

func Contains

func Contains[T Verifiable](v T, vs []T) bool

Contains checks if a slice contains a specific element.

It takes a slice and an element of the same type as input, and returns a boolean value indicating whether the element is found in the slice.

T is the type of items in the slice and the element to be searched. The function returns true if the element is found, and false otherwise.

Example usage:

numSlice := []int{1, 2, 3, 4, 5}
resultNum := g.Contains(3, numSlice)
fmt.Println(resultNum) // Output: true

strSlice := []string{"Hello", "World", "Golang"}
resultStr := g.Contains("Python", strSlice)
fmt.Println(resultStr) // Output: false

func DateToString added in v1.6.0

func DateToString(t time.Time, patterns ...string) (string, error)

DateToString converts a Date to a string based on the provided format.

If multiple formats are provided, only the first one will be processed.

Example usage:

date := time.Date(2023, 7, 17, 0, 0, 0, 0, time.UTC)
s, err := DateToString(date, "2006-01-02")
if err != nil {
  log.Fatal(err)
}
fmt.Println(s)  // Output: "2023-07-17"

func DateToStrings added in v1.6.0

func DateToStrings(t time.Time, patterns ...string) ([]string, error)

DateToStrings converts a Time object into string(s) using the provided formats. The function uses time.DateTime format as a default option if no format is provided. In case the pattern includes a percentage ("%") character, it converts Python strftime format to Go's time format before applying it.

It returns an array of the results and an error if there was a problem with the formatting.

Example usage:

t := time.Now()
patterns := []string{"%Y-%m-%d", "02 Jan 06", time.RFC3339}
results, err := DateToStrings(t, patterns...)

if err != nil {
	log.Fatal(err)
	return
}

for i, str := range results {
	fmt.Printf("Date in format %s: %s\n", patterns[i], str)
}

func Diff

func Diff[T comparable](a []T, b []T) []T

Diff is an alias for Difference function.

func Difference

func Difference[T comparable](a []T, b []T) []T

Difference takes two slices and returns a new slice that contains the items present in the first slice but not in the second slice. The type T must be comparable.

The function returns the difference of the slices.

The function is generic and can work with any type T that is comparable.

Note: This function does not preserve the order of elements. The order of elements in the returned slice can be different from the order of elements in the input slices.

Example usage:

a := []int{1, 2, 3}
b := []int{3, 4, 5}
result := g.Difference(a, b)
fmt.Println(result) // Output: [1, 2]

a := []string{"a", "b", "c"}
b := []string{"c", "d", "e"}
result := g.Difference(a, b)
fmt.Println(result) // Output: ["a", "b"]

func Distinct

func Distinct[T comparable](v []T) []T

Distinct returns a new slice with unique values from the input slice.

It removes duplicates from the input slice and returns a new slice with unique values in the same order as they appear in the input slice.

This function is generic and can work with any type T.

Example usage:

// If you have a slice with duplicates:
numbers := []int{1, 2, 2, 3, 3, 3, 4, 4, 4, 4}
uniqueNumbers := g.Distinct(numbers)
fmt.Println(uniqueNumbers)  // Output: [1 2 3 4]

// This function also works with slices of other comparable types,
// like strings:
words := []string{"hello", "world", "hello", "gophers"}
uniqueWords := g.Distinct(words)
fmt.Println(uniqueWords)  // Output: ["hello" "world" "gophers"]

func Filter

func Filter[T any](vs []T, f func(T) bool) []T

Filter applies a predicate function to all items in an input slice and returns a new slice with the items for which the predicate function returns true.

T is the type of items in the input slice. The predicate function f takes an item of type T and returns a boolean.

Example usage:

// Let's say you have a slice of integers and you want
// to filter out even numbers:
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
evens := g.Filter(nums, func(v int) bool { return v%2 == 0 })
fmt.Println(evens) // Output: [2 4 6 8 10]

// Or you may have a slice of strings and you want
// to filter out strings with length greater than 5:
strs := []string{"apple", "banana", "cherry", "date", "elderberry"}
longStrings := g.Filter(strs, func(v string) bool { return len(v) > 5 })
fmt.Println(longStrings) // Output: ["banana" "cherry" "elderberry"]

func FloatToString added in v1.13.0

func FloatToString[T ~float32 | ~float64](v T) string

FloatToString converts a float to a string. It handles different floating-point types such as float32 and float64.

func HLookup

func HLookup[T comparable, U any](v T, lookup []T, result []U, def U) U

HLookup looks up and retrieves data from a specific row in a table.

The function takes a search value `v`, a slice of lookup values `lookup`, a slice of result values `result`, and an optional default value `def`. It searches for the first occurrence of `v` in the `lookup` slice and Output: the corresponding value from the `result` slice. If `v` is not found in the `lookup` slice, it returns the default value `def`.

Example usage:

// Perform a horizontal lookup on a string slice and retrieve the
// corresponding value from an int slice.
lookup := []string{"A", "B", "C"}
result := []int{1, 2, 3}
val := g.HLookup("B", lookup, result, -1)
fmt.Println(val) // Output: 2

// Perform a horizontal lookup on a string slice with a value that
// doesn't exist, and return the default value.
val = g.HLookup("D", lookup, result, -1)
fmt.Println(val) // Output: -1

func If

func If[L bool | trit.Trit, T any](e L, t, f T, u ...T) T

If is a substitute for the ternary operator (?:) which is not available in Go.

In languages like C/C++ and Python, you can use a ternary operator for a concise conditional expression:

C/C++:  int max = (a > b) ? a : b;
Python: max = a if a > b else b

It takes three parameters: a boolean expression e, and two values of any type T (t and f). If the expression e is true, it returns t, otherwise it returns f.

Example usage:

// Condition is true.
max := g.If(3 > 2, 3, 2)  // Output: 3

// If condition is false.
max := g.If(2 > 3, 2, 3)  // Output: 3

// Using with strings.
greeting := g.If(user == "admin", "Hello, admin", "Hello, user")
fmt.Println(greeting) // Output: the appropriate greeting

The function can work with Trit types, so it can get the status Unknown. In this case, if the function receives two possible solutions, it will return the second one (false):

max := g.If(trit.Unknown, 3, 2)  // Output: 2

This function can accept an optional argument u, for cases of working with Trit types. In this case, if Trit is Unknow, the third value will be returned:

max := g.If(trit.Unknown, 3, 2, 1)  // Output: 1

If more than 3 possible result values are passed, the others of the results will be ignored. The third and more likely results are ignored for boolean expression values.

max := g.If(trit.Unknown, 3, 2, 1, 5, 7)  // Output: 1 and 5, 7 are ignored
min := g.If(3 > 2, 3, 2, 1, 5, 7)  // Output: 3 and 1, 5, 7 are ignored

func In

func In[T Verifiable](v T, list ...T) bool

In is a generic function that checks if a given value 'v' of type 'T' exists in a variadic parameter list of 'T'. The function uses the 'Verifiable' type constraint which allows it to operate on numeric types and strings.

This function leverages goroutines for concurrent computation when the size of the list is large. It splits the list into chunks (based on the number of CPU cores) and checks each chunk in a separate goroutine. This allows the function to take advantage of multi-core processors and improves performance on large data sets.

A 'sync.WaitGroup' is used to ensure all goroutines have completed, and a thread-safe structure 'Found' is used to safely access the shared 'found' variable across goroutines.

Usage:

// Define a slice of integers.
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

// Check if '5' exists in the slice.
exists := g.In(5, numbers...)
fmt.Println(exists)  // Output: true

// Define a slice of strings.
words := []string{"apple", "banana", "cherry", "date", "elderberry"}

// Check if 'date' exists in the slice
exists = g.In("date", words...)
fmt.Println(exists)  // Output: true

func Index

func Index[T comparable](vs []T, v T) int

Index returns the index of the first occurrence of a specific element in a slice, or -1 if the element is not present.

T is the type of the items in the slice and the element to be searched. The function returns an integer indicating the position of the first occurrence of the element, or -1 if the element is not found.

Example usage:

// Let's say you have a slice of integers and you want
// to find the index of the number 7:
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
idx := g.Index(nums, 7)
fmt.Println(idx) // Output: 6

// Or you have a slice of strings and you want to find
// the index of the string "cherry":
fruits := []string{"apple", "banana", "cherry", "date", "elderberry"}
idx := g.Index(fruits, "cherry")
fmt.Println(idx) // Output: 2

// In case the element is not in the slice, the function will return -1:
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
idx := g.Index(nums, 11)
fmt.Println(idx) // Output: -1

func IntToString added in v1.13.0

func IntToString[T Integer](v T) string

IntToString converts an integer to a string. It handles different integer types such as int, int64, int32, uint, uint64,uint32, etc.

func Intersection

func Intersection[T comparable](a []T, b []T) []T

Intersection takes two slices and returns a new slice that contains the common items present in both slices. The type T must be comparable.

The function returns the intersection of the slices.

The function is generic and can work with any type T that is comparable.

Note: This function does not preserve the order of elements. The order of elements in the returned slice can be different from the order of elements in the input slices.

Example usage:

a := []int{1, 2, 3}
b := []int{3, 4, 5}
result := g.Intersection(a, b)
fmt.Println(result) // Output: [3]

a := []string{"a", "b", "c"}
b := []string{"c", "d", "e"}
result := g.Intersection(a, b)
fmt.Println(result) // Output: [c]

func IsEmpty

func IsEmpty[T any](v T) bool

IsEmpty checks if the v of any type T is "zero value" for that type.

Zero values in Go are values that the variables of respective types hold upon their declaration, if they do not have any explicit initialization.

For example, zero value of type int is 0, for type float64 is 0.0, for a pointer is nil, for a string is "", for a boolean is false, etc.

Example usage:

// Check if an integer variable is zero.
var num int
result := g.IsEmpty(num)
fmt.Println(result) // Output: true

// Check if a float variable is zero.
var f float64
result := g.IsEmpty(f)
fmt.Println(result) // Output: true

// Check if a pointer variable is nil.
var ptr *int
result := g.IsEmpty(ptr)
fmt.Println(result) // Output: true

// Check if a string variable is empty.
var str string
result := g.IsEmpty(str)
fmt.Println(result) // Output: true

// Check if a boolean variable is false.
var flag bool
result := g.IsEmpty(flag)
fmt.Println(result) // Output: true

func IsEven

func IsEven[T Numerable](v T, f ...bool) bool

IsEven checks if a value is an even number.

The function accepts a value of any type T that satisfies the Numerable interface. If the `f` argument is provided and set to true, the function ignores the fractional part of the value when checking for evenness. For integer types, it checks if the value is divisible by 2 without a remainder. For floating-point types, it considers only the integer part of the value and determines the parity of the integer part. If the value has a non-zero fractional part and `f` is true, it returns false since an even number cannot have a fractional part.

Example usage:

even := g.IsEven(6)
fmt.Println(even)  // Output: true

odd := g.IsEven(7)
fmt.Println(odd)  // Output: false

floatingPoint := g.IsEven(6.6)
fmt.Println(floatingPoint)  // Output: false

floatingPoint = g.IsEven(6.6, true)
fmt.Println(floatingPoint)  // Output: true

func IsFalse added in v1.9.0

func IsFalse[T any](v T) bool

IsFalse checks if the v of any type T is true value for that type.

P.s. trit.False and trit.Unknown are false values.

func IsNumber

func IsNumber(v interface{}) bool

IsNumber checks if a value is a numeric type.

The function takes an interface{} value `v` and checks if it is of a numeric type, including integer and floating-point types. It returns true if `v` is a numeric type, and false otherwise.

Example usage:

// Check if an integer variable is a numeric type.
num := 10
result := g.IsNumber(num)
fmt.Println(result) // Output: true

// Check if a float variable is a numeric type.
f := 3.14
result = g.IsNumber(f)
fmt.Println(result) // Output: true

// Check if a string variable is a numeric type.
str := "hello"
result = g.IsNumber(str)
fmt.Println(result) // Output: false

// Check if a boolean variable is a numeric type.
flag := true
result = g.IsNumber(flag)
fmt.Println(result) // Output: false

// Check if a slice of integers is a numeric type.
nums := []int{1, 2, 3}
result = g.IsNumber(nums)
fmt.Println(result) // Output: false

func IsOdd

func IsOdd[T Numerable](v T, f ...bool) bool

IsOdd checks if a value is an odd number.

The function accepts a value of any type T that satisfies the Numerable interface. If the `f` argument is provided and set to true, the function ignores the fractional part of the value when checking for oddness. For integer types, it checks if the value is not divisible by 2 without a remainder. For floating-point types, it considers only the integer part of the value and determines the parity of the integer part. If the value has a non-zero fractional part and `f` is true, it returns true since an odd number cannot have a fractional part. Otherwise, it returns the negation of the IsEven function.

Example usage:

odd := g.IsOdd(7)
fmt.Println(odd)  // Output: true

even := g.IsOdd(6)
fmt.Println(even)  // Output: false

floatingPoint := g.IsOdd(7.7)
fmt.Println(floatingPoint)  // Output: false

floatingPoint = g.IsOdd(7.7, true)
fmt.Println(floatingPoint)  // Output: true

func IsPointer

func IsPointer(v interface{}) bool

IsPointer checks if a value is a pointer.

The function takes an interface{} value `v` and checks if it is a pointer type. It returns true if `v` is a pointer, and false otherwise.

Example usage:

// Check if a variable holding a pointer to a string is a pointer.
str := "hello"
result := g.IsPointer(&str)
fmt.Println(result) // Output: true

// Check if a variable holding a string is a pointer.
result = g.IsPointer(str)
fmt.Println(result) // Output: false

// Check if a variable holding an integer is a pointer.
result = g.IsPointer(10)
fmt.Println(result) // Output: false

// Check if a variable holding nil is a pointer.
var ptr *int
result = g.IsPointer(ptr)
fmt.Println(result) // Output: false

func IsTrue added in v1.9.0

func IsTrue[T any](v T) bool

IsTrue checks if the v of any type T is true value for that type.

P.s. trit.False and trit.Unknown are false values.

func IsWhole

func IsWhole[T Numerable](v T) bool

IsWhole checks if a value is a whole number.

The function accepts a value of any type T that satisfies the Numerable interface. It first checks if the value has a non-zero fractional part. If it does, it returns false since a whole number cannot have a fractional part. If the value does not have a fractional part, it returns true.

Example usage:

whole := g.IsWhole(5)
fmt.Println(whole)  // Output: true

notWhole := g.IsWhole(5.5)
fmt.Println(notWhole)  // Output: false

zero := g.IsWhole(0)
fmt.Println(zero)  // Output: true

negative := g.IsWhole(-3)
fmt.Println(negative)  // Output: true

func Map

func Map[T any, U any](vs []T, f func(T) U) []U

Map applies a function to all items in an input slice and returns a new slice with the transformed items.

T is the type of items in the input slice, and U is the type of items in the output slice. The function f takes an item of type T and returns a new item of type U.

Example usage:

// Let's say you have a slice of integers and you want to create a
// new slice where each element is the square of the original element:
nums := []int{1, 2, 3, 4, 5}
squares := g.Map(nums, func(n int) int {
   return n * n
})
fmt.Println(squares) // Output: [1 4 9 16 25]

// Or you have a slice of strings and you want to create a new slice
// where each element is the length of the original string:
fruits := []string{"apple", "banana", "cherry", "date", "elderberry"}
lengths := g.Map(fruits, func(s string) int {
   return len(s)
})
fmt.Println(lengths) // Output: [5 6 6 4 10]

func Max

func Max[T Verifiable](v ...T) T

Max returns the largest value among all input values.

The function iterates through all the passed values and returns the largest one. The type must be Verifiable and support the greater than (>) operator.

Example usage:

values := []int{3, 5, 7, 1, 9, 2}
maxI := g.Max(values...)
fmt.Println(maxI)  // Output: 9

floats := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
maxF: = g.Max(floats...)
fmt.Println(maxF)  // Output: 5.5

func MaxList

func MaxList[T Verifiable](v []T, defaults ...T) T

MaxList returns the largest value among all input values in a list.

This function requires a list of values of a type that satisfies the Verifiable interface. It also accepts optional default values, which are used when the input list is empty.

If the input list is empty:

  • If defaults are provided, the maximum value among the defaults is returned.
  • If no defaults are provided, the function returns the minimal value for the Verifiable type.

Example usage:

values := []int{3, 5, 7, 1, 9, 2}
max := g.MaxList(values)
fmt.Println(max)  // Output: 9

floats := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
max = g.MaxList(floats)
fmt.Println(max)  // Output: 5.5

empty := []int{}
defaults := []int{4, 5, 6}
max = g.MaxList(empty, defaults...)
fmt.Println(max)  // Output: 6

func Median

func Median[T Numerable](v ...T) float64

Median calculates the median value of a variable number of values of type Numerable.

It takes a slice of values of type T and returns the median value as a float64. The type T must satisfy the Numerable interface.

The median is the middle value of a sorted list of values. If the number of values is odd, the median is the middle value. If the number of values is even, the median is the average of the two middle values.

Example usage:

values := []int{3, 5, 7, 1, 9, 2}
median := g.Median(values...)
fmt.Println(median)  // Output: 4.0

floats := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
median = g.Median(floats...)
fmt.Println(median)  // Output: 3.3

func Merge

func Merge[T Verifiable](a []T, b []T, sort ...bool) []T

Merge merges two sorted arrays into a single sorted array.

It takes two sorted arrays a and b as input and returns a single sorted array that contains all the elements from both arrays.

The function assumes that both input arrays are already sorted in ascending order.

Example:

a := []int{1, 3, 5}
b := []int{2, 4, 6}
mergedUnsort := g.Merge(a, b)     // [1 3 5 2 4 6]
mergedSort := g.Merge(a, b, true) // [1 2 3 4 5 6]

This function is generic and can work with any type T.

func Min

func Min[T Verifiable](v ...T) T

Min returns the smallest value among all input values.

The function iterates through all the passed values and returns the smallest one. The type must be Verifiable and support the less than (<) operator.

Example usage:

values := []int{3, 5, 7, 1, 9, 2}
minI := g.Min(values...)
fmt.Println(minI)  // Output: 1

floats := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
minF = g.Min(floats...)
fmt.Println(minF)  // Output: 1.1

strings := []string{"z", "a", "m", "c", "y"}
minS = g.Min(strings...)
fmt.Println(minS)  // Output: a

func MinList

func MinList[T Verifiable](v []T, defaults ...T) T

MinList returns the smallest value among all input values in a list.

This function requires a list of values of a type that satisfies the Numerable interface. It also accepts optional default values, which are used when the input list is empty.

If the input list is empty:

  • If defaults are provided, the minimum value among the defaults is returned.
  • If no defaults are provided, the function returns the minimum value for the Verifiable type.

Example usage:

values := []int{3, 5, 7, 1, 9, 2}
minI := g.MinList(values)
fmt.Println(minI)  // Output: 1

floats := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
minF = g.MinList(floats)
fmt.Println(minF)  // Output: 1.1

empty := []int{}
defaults := []int{4, 5, 6}
minD := g.MinList(empty, defaults...)
fmt.Println(minD)  // Output: 4

func MoveTimeZone added in v1.7.0

func MoveTimeZone(t time.Time, tz int) time.Time

MoveTimeZone adds or subtracts multiple time zones from a given time. The function uses the time.Duration type to add/subtract hours from the current time. Positive 'tz' values move the time forward, and negative values move it backward.

Example usage:

t := time.Now()
newTime := MoveTimeZone(t, -3)
fmt.Println(newTime)
// Output: <current time minus 3 hours>

func ParallelTasks

func ParallelTasks(v ...int) int

ParallelTasks returns the number of parallel tasks.

If the function is called without parameters, it returns the current value of parallelTasks.

A function can receive one or more values for parallelTasks, these values are added together to form the final result for parallelTasks. If the new value for parallelTasks is less than or equal to zero - it will be set to 1, if it is greater than maxParallelTasks - it will be set to maxParallelTasks.

func Preserve added in v1.4.0

func Preserve(s string, patterns ...string) string

Preserve keeps only characters specified by the patterns in the string.

It is a utility function that helps you to 'preserve' only the characters you want in your strings. Just as an archaeologist would go through a site preserving important artefacts, this function iterates over the string and keeps only the characters specified as patterns.

By default, if no patterns are specified, it keeps only alphanumeric characters (i.e., letters, numbers and space). However, you can specify your own patterns to fit your needs. The function uses an efficient mapping approach to achieve this, making it effective for processing large strings.

Example usage:

g.Preserve("Hello, World!")                 // Output: "Hello World"
g.Preserve("+380 (96) 123 4567", g.Numbers) // Output: "380961234567"

func Product

func Product[T Numerable](v ...T) T

Product calculates the product of all numeric values in the input slice.

It iterates through the input slice and multiplies all the numeric values together to compute the product. The type T must satisfy the Numerable interface.

If there are no numeric values in the slice, the function returns 1.

Example usage:

// Calculate the product of a slice of integers:
nums := []int{2, 3, 4}
p := g.Product(nums)
fmt.Println(p)  // Outputs: 24

// Compute the product of a slice of floats:
nums := []float64{1.2, 3.4, 5.6}
p := g.Product(nums)
fmt.Println(p)  // Outputs: 22.848

// If the slice is empty, the function returns 1:
nums := []int{}
p := g.Product(nums)
fmt.Println(p)  // Outputs: 1

func Ptr added in v1.11.0

func Ptr[T any](v ...T) *T

Ptr creates a pointer from a literal or defaults to a pointer to a zero value of T if no arguments are given. This function is particularly useful when a pointer to a literal or default zero value is needed directly in expressions or function calls, simplifying syntax and avoiding the need for temporary variables.

Parameters:

v ...T - An optional variable of type T from which to create a pointer.
         If not provided, the function returns a pointer to the zero
         value of T.

Returns:

*T - A pointer to the value of T provided, or to the zero value of T
     if none is provided.

Example usage:

// Function that returns an int value.
func Sum(a, b int) int { return a + b }

// Function that requires a pointer to an int.
func IsMoreThanTen(n *int) bool { return *n > 10 }

// Classical usage with variable.
v := Sum(3, 7)
r1 := IsMoreThanTen(&v)

// Using Ptr to simplify passing a pointer to a function.
r2 := IsMoreThanTen(Ptr(Sum(3, 7)))

// Create a pointer from a literal.
r3 := IsMoreThanTen(Ptr(21))

// Get a pointer to the zero value of the specified type.
zeroPtr := Ptr[int]()

// Specify the type of the literal.
var int64Ptr *int64 = Ptr[int64](21)

func PtrIf added in v1.12.0

func PtrIf[T any](exp bool, v ...T) *T

PtrIf conditionally creates a pointer to a given value or returns nil based on a boolean expression. This function simplifies pointer management in conditional logic, avoiding the need for temporary variables or manual pointer handling.

Parameters:

exp bool - A boolean expression that determines whether a pointer
           is returned or nil.
v ...T   - An optional variable of type T from which to create a
           pointer. If the expression is false, or no value is
           provided, the function returns nil.

Returns:

*T - A pointer to the value of T if the expression is true and a value
     is provided, otherwise nil.

Example usage:

// where returns a WHERE clause for a SQL query based on the provided
// boolean values. It accepts three boolean pointers: isActive, isStaff,
// and isSuperuser. If any of these pointers are nil, the corresponding
// condition is not included in the WHERE clause.
func where(isActive, isStaff, isSuperuser *bool) string {
	check := [...]struct {
		name  string
		value *bool
	}{
		{name: "is_active", value: isActive},
		{name: "is_staff", value: isStaff},
		{name: "is_superuser", value: isSuperuser},
	}

    and := make([]string, 0, len(check))
    for _, m := range check {
    	if m.value != nil {
    		and = append(and, fmt.Sprintf("%s=%t", m.name, *m.value))
    	}
    }

    if len(and) != 0 {
    	return "WHERE " + strings.Join(and, ", ")
    }

	return ""
}

// Some data is stored in map.
argsMap := make(map[string]bool)
argsMap["isActive"] = true
argsMap["isStaff"] = false

// Using PtrIf to conditionally pass pointers.
isActive, isActiveOk := argsMap["isActive"]
isStaff, isStaffOk := argsMap["isStaff"]
isSuperuser, isSuperuserOk := argsMap["isSuperuser"]
query := where(
    g.PtrIf(isActiveOk, isActive),
    g.PtrIf(isStaffOk, isStaff),
    g.PtrIf(isSuperuserOk, isSuperuser), // nil pointer
) // Result: "WHERE is_active=true, is_staff=false"

func Random

func Random[T Numerable](v ...T) T

Random generates a random value of type T based on provided arguments:

  • When called without any arguments, it returns 0.
  • When called with one argument, it returns a random value from 0 to n-1.
  • When called with two arguments, it returns a random value from a to b-1.
  • When called with more than two arguments, it returns a randomly selected value from the provided arguments.

The function uses the time in nanoseconds as a seed for the random number generator.

Example usage:

rand0 := g.Random[int]()
fmt.Println(rand0)  // Output: 0

rand1 := g.Random[int](5)
fmt.Println(rand1)  // Output: a random int from 0 to 4

rand2 := g.Random[int](1, 5)
fmt.Println(rand2)  // Output: a random int from 1 to 4

rand3 := g.Random[int](1, 2, 3)
fmt.Println(rand3)  // Output: 1, 2, or 3

func RandomList

func RandomList[T any](v []T) T

RandomList returns a random element from the given list. If the list is empty, it returns the zero value of type T.

Example usage:

list := []int{1, 2, 3, 4, 5}
value := g.RandomList(list)
fmt.Println(value)  // Output: a random element from the list

emptyList := []string{}
value := g.RandomList(emptyList)
fmt.Println(value)  // Output: ""

func RandomListPlural

func RandomListPlural[T any](n int, v []T) []T

RandomListPlural returns a slice of n random elements from the given list v. If n is less than or equal to zero, it returns an empty slice.

Example usage:

list := []int{1, 2, 3, 4, 5}
values := g.RandomListPlural(3, list)
fmt.Println(values)  // Output: a slice of 3 random elements from the list

emptyList := []string{}
values := g.RandomListPlural(2, emptyList)
fmt.Println(values)  // Output: []

values := g.RandomListPlural(0, list)
fmt.Println(values)  // Output: []

func RandomMap

func RandomMap[K comparable, T any](m map[K]T) T

RandomMap returns a random value from the given map. If the map is empty, it returns the zero value of type T.

Example usage:

myMap := map[string]int{
    "apple":  1,
    "banana": 2,
    "cherry": 3,
}
value := g.RandomMap(myMap)
fmt.Println(value)  // Output: a random value from the map

emptyMap := map[string]bool{}
value := g.RandomMap(emptyMap)
fmt.Println(value)  // Output: zero value for T type (false)

func RandomMapPlural

func RandomMapPlural[K comparable, T any](n int, m map[K]T) []T

RandomMapPlural returns a slice of n random values from the given map m. If n is less than or equal to zero, it returns an empty slice.

Example usage:

myMap := map[string]int{
    "apple":  1,
    "banana": 2,
    "cherry": 3,
}
values := g.RandomMapPlural(2, myMap)
fmt.Println(values)  // Output: a slice of 2 random values from the map

emptyMap := map[string]bool{}
values := g.RandomMapPlural(3, emptyMap)
fmt.Println(values)  // Output: []

values := g.RandomMapPlural(0, myMap)
fmt.Println(values)  // Output: []

func Range added in v1.1.0

func Range(a int, opt ...int) []int

Range generates a slice of integers based on the provided parameters. Returns nil if the parameters are invalid.

  • If a single parameter is passed (Range(n)), the function returns a slice from 0 to n-1.
  • If two parameters are passed (Range(n, m)), the function returns a slice from n to m-1.
  • If three parameters are passed (Range(n, m, s)), the function returns a slice from n to m-1 with a step size of s.

The function returns nil if:

  • The step size is zero
  • The range is decreasing but step is positive
  • The range is increasing but step is negative
  • The resulting sequence would exceed MaxRangeSize

The maximum size of the generated slice is set by the MaxRangeSize constant.

Example usage:

result := g.Range(5)
// Output: [0, 1, 2, 3, 4]

result := g.Range(3, 7)
// Output: [3, 4, 5, 6]

result := g.Range(1, 10, 2)
// Output: [1, 3, 5, 7, 9]

result := g.Range(10, 0, -1)
// Output: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

result := g.Range(1, 10, 0)
// Output: nil - step size cannot be zero

result := g.Range(10, 1, 1)
// Output: nil - decreasing range with positive step

func Rangef added in v1.2.0

func Rangef[T any](fn func(int) T, a int, opt ...int) []T

Rangef generates a slice of values based on the provided parameters and a given function as func(int) T. Returns nil if the parameters are invalid.

  • If a single parameter is passed (Range(fn, n)), the function returns a slice from 0 to n-1 and pass it in fn.
  • If two parameters are passed (Range(fn, n, m)), the function returns a slice from n to m-1 and pass it in fn.
  • If three parameters are passed (Range(fn, n, m, s)), the function returns a slice from n to m-1 with a step size of s, and pass it in fn.

The function returns nil if:

  • The step size is zero
  • The range is decreasing but step is positive
  • The range is increasing but step is negative
  • The resulting sequence would exceed MaxRangeSize

Example usage:

func appleFactory() func(int) string {
    var appleVarieties = []string{
        "Gala",
        "Fuji",
        "Honeycrisp",
        "Red Delicious",
        "Granny Smith",
        "Golden Delicious",
        "Pink Lady",
        "Braeburn",
        "McIntosh",
        "Jazz",
    }

    return func(i int) string {
        if i >= 0 && i < len(appleVarieties) {
            return appleVarieties[i]
        }
        return "-"
    }
}

result := g.Rangef(appleFactory(), 3)
// Output: [Gala Fuji Honeycrisp]

result := g.Rangef(appleFactory(), 4, 7)
// Output: [Granny Smith Golden Delicious Pink Lady]

result := g.Rangef(appleFactory(), 7, 12, 2)
// Output: [Braeburn Jazz -]

result := g.Rangef(appleFactory(), 1, 10, 0)
// Output: nil - step size cannot be zero

func Rank

func Rank[T Verifiable](number T, array []T, ascending ...bool) int

Rank function returns the rank of a value when compared to a list of other values. Rank can rank values from largest to smallest (i.e. top sales) as well as smallest to largest (i.e. fastest time).

It is not necessary to sort the values in the list before using Rank.

The function has two modes of operation, controlled by the ascending argument. To rank values where the largest value is ranked #1, set ascending to false (or leave blank).

g.Rank(7, []float64{1, 5, 2, 3, 7, 8})       // descending, returns  1
g.Rank(7, []float64{1, 5, 2, 3, 7, 8}, true) // ascending, returns 4

Set ascending to false when you want to rank something like top sales, where the largest sales number should rank #1, and to set ascending to true when you want to rank something like race results, where the shortest (fastest) time should rank #1.

The Rank function will assign duplicate values to the same rank. For example, if a certain value has a rank of 3, and there are two instances of the value in the data, the Rank function will assign both instances a rank of 3. The next rank assigned will be 5, and no value will be assigned a rank of 4. If tied ranks are a problem, one workaround is to employ a tie-breaking strategy.

The function works with both numbers and strings, all that satisfy the Verifiable interface.

Example usage:

// Rank a number in a descending list.
result := g.Rank(7, []float64{1, 5, 2, 3, 7, 8})
fmt.Println(result) // Output: 1

// Rank a number in an ascending list.
result = g.Rank(7, []float64{1, 5, 2, 3, 7, 8}, true)
fmt.Println(result) // Output: 4

// Rank a number that doesn't exist in the list.
result = g.Rank(9, []float64{1, 5, 2, 3, 7, 8}, true)
fmt.Println(result) // Output: -1

func Reduce

func Reduce[T any, U any](vs []T, f func(U, T) U, init U) U

Reduce takes a slice, an initial value and a fold function as input, and it returns a single value that results from applying the fold function to each item in the slice in order.

T is the type of items in the slice. U is the type of the output and the initial value.

The fold function f takes two parameters - an accumulator of type U and an item of type T, and returns a new accumulator.

Example usage:

// Let's say you have a slice of integers and you want to
// compute the sum of all elements:
nums := []int{1, 2, 3, 4, 5}
sum := go.Reduce(nums, func(acc int, n int) int {
   return acc + n
}, 0)
fmt.Println(sum) // Output: 15

// Or you have a slice of strings and you want to concatenate
// them all into a single string:
words := []string{"Hello", "World", "From", "Go"}
sentence := go.Reduce(words, func(acc string, s string) string {
   return acc + " " + s
}, "")
fmt.Println(sentence) // Output: "Hello World From Go"

func Reverse added in v1.3.0

func Reverse[T any](v []T)

Reverse changes slice with elements in reverse order.

It takes a slice 'v' of any type 'T' and swaps the elements in-place to reverse their order.

Example usage:

numbers := []int{1, 2, 3, 4, 5}
Reverse(numbers)
// numbers: [5, 4, 3, 2, 1]

names := []string{"Alice", "Bob", "Charlie", "Dave"}
Reverse(names)
// names: ["Dave", "Charlie", "Bob", "Alice"]

empty := []bool{}
Reverse(empty)
// empty: []

func SafeSum added in v1.14.0

func SafeSum[T Numerable](v ...T) (T, error)

SafeSum returns the sum of all values with overflow checking.

This function performs addition with overflow detection for integer types. If an overflow occurs, it returns an error. For floating-point types, it sums the values without overflow checking.

Example usage:

// Safe sum with integers.
values := []int{math.MaxInt, 1}
sum, err := SafeSum(values...)
if err != nil {
    fmt.Println("Error:", err)  // Output: Error: integer overflow occurred
} else {
    fmt.Println("Sum:", sum)
}

// Safe sum with floats.
floatValues := []float64{1.1, 2.2, 3.3}
sum, err = SafeSum(floatValues...)
if err != nil {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Sum:", sum)  // Output: Sum: 6.6
}

func Sdiff

func Sdiff[T comparable](a []T, b []T) []T

Sdiff is an alias for SymmetricDifference function.

func SetTimeZone added in v1.7.0

func SetTimeZone(t time.Time, timezone string) (time.Time, error)

SetTimeZone changes the time zone, and changes the local time according to the new time zone. This can be used to convert the time from one time zone to another. The time value will adjust to maintain the same moment in time, but the hour, minute, and second may change.

Example usage:

t, _ := time.Parse(time.RFC3339, "2023-06-17T08:15:45Z")
newTime, err := SetTimeZone(t, "America/New_York")
if err != nil {
    log.Fatal(err)
}
fmt.Println(newTime)
// Output: 2023-06-17 04:15:45 -0400 EDT

func Shuffle

func Shuffle[T any](v []T)

Shuffle randomly shuffles the elements in the input slice.

It modifies the input slice in-place by rearranging the elements in a random order using the Fisher-Yates algorithm.

This function is generic and can work with any type T.

Example usage:

// If you have a slice and want to shuffle its elements:
numbers := []int{1, 2, 3, 4, 5}
g.Shuffle(numbers)
fmt.Println(numbers)
// Prints the slice numbers in a random order, e.g., [3 1 5 2 4]

// This function also works with slices of other types, like strings:
words := []string{"hello", "world", "gophers", "Go", "OpenAI"}
g.Shuffle(words)
fmt.Println(words)
// Prints the slice words in a random order, e.g.,
// ["Go" "gophers" "hello" "OpenAI" "world"]

func Sort

func Sort[T Verifiable](v []T, inverse ...bool)

Sort sorts the values in a slice in either ascending or descending order.

This function modifies the original slice in-place and doesn't return a new slice. The type T must satisfy the Numerable interface.

If the `inverse` argument is provided and set to true, the values are sorted in descending order. Otherwise, the values are sorted in ascending order.

The function uses the quicksort algorithm to sort the values.

Example usage:

// If you have a slice of integers that you want
// to sort in ascending order:
nums := []int{5, 2, 7, 8, 1, 9}
g.Sort(nums)
fmt.Println(nums) // Output: [1 2 5 7 8 9]

// If you want to sort the same slice in descending order:
nums := []int{5, 2, 7, 8, 1, 9}
g.Sort(nums, true)
fmt.Println(nums) // Output: [9 8 7 5 2 1]

// This function is generic and can work with any type
// that satisfies the Numerable interface.
// For example, if you have a slice of floats:
floats := []float64{5.5, 2.2, 7.7, 8.8, 1.1, 9.9}
g.Sort(floats)
fmt.Println(floats) // Output: [1.1 2.2 5.5 7.7 8.8 9.9]

func StringToBool added in v1.13.0

func StringToBool(v string, def ...bool) (bool, error)

StringToBool converts a string to a boolean. It handles various string representations of boolean values such as "true", "false", "yes", "no", "on", "off". If the conversion fails and a default value is provided, it returns the default value. Otherwise, it returns an error.

Example Usage:

b, err := StringToBool("true") // true, nil
b, err := StringToBool("yes")  // true, nil
b, err := StringToBool("abc", false) // false, error

func StringToDate added in v1.6.0

func StringToDate(s string, patterns ...string) (time.Time, error)

StringToDate converts a string to a time.Time object using the provided formats. If no format is given, it uses default date-time formats.

This function leverages goroutines to parse the string concurrently using different formats. When the first successful parsing occurs, the function stops all other goroutines and returns the result. If no parsing is successful, the function returns an error.

Example usage:

// Automatic pattern detection.
t, err := StringToDate("2006-01-02")
if err != nil {
    log.Fatal(err)
}
fmt.Println(t)

t, err = StringToDate("2006/01/02 15:04:05")
if err != nil {
    log.Fatal(err)
}
fmt.Println(t)

// Using custom formats as Python.
t, err = StringToDate("Jan 02, 2006", "%b %d, %Y")
if err != nil {
    log.Fatal(err)
}
fmt.Println(t)

// Using Go's date formatting
t, err = StringToDate("Jan 02, 2006", "Jan 02, 2006")
if err != nil {
    log.Fatal(err)
}
fmt.Println(t)

func StringToFloat added in v1.13.0

func StringToFloat(v string, def ...float64) (float64, error)

StringToFloat converts a string to a float. If the conversion fails and a default value is provided, it returns the default value. Otherwise, it returns an error.

Example Usage:

f, err := StringToFloat("3.14") // 3.14, nil
f, err := StringToFloat("abc", 1.23) // 1.23, error

func StringToInt added in v1.13.0

func StringToInt(v string, def ...int) (int, error)

StringToInt converts a string to an integer. If the conversion fails and a default value is provided, it returns the default value. Otherwise, it returns an error.

Example Usage:

i, err := StringToInt("41") // 41, nil
i, err := StringToInt("abc", 7) // 7, error

func Sum

func Sum[T Numerable](v ...T) T

Sum returns the sum of all values.

Note: This function does not handle overflow. If the sum of the input values exceeds the maximum value that can be stored in type T, the function returns the zero value of type T.

Example usage:

values := []int{3, 5, 7, 1, 9, 2}
sum := Sum(values...)
fmt.Println(sum)  // Output: 27

floats := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
sum = Sum(floats...)
fmt.Println(sum)  // Output: 16.5

func SymmetricDifference

func SymmetricDifference[T comparable](a []T, b []T) []T

SymmetricDifference takes two slices and returns a new slice that contains the items present in one of the slices but not in both. The type T must be comparable.

The function returns the symmetric difference of the slices.

The function is generic and can work with any type T that is comparable.

Note: This function does not preserve the order of elements. The order of elements in the returned slice can be different from the order of elements in the input slices.

Example usage:

a := []int{1, 2, 3}
b := []int{3, 4, 5}
result := g.SymmetricDifference(a, b)
fmt.Println(result) // Output: [1, 2, 4, 5]

a := []string{"a", "b", "c"}
b := []string{"c", "d", "e"}
result := g.SymmetricDifference(a, b)
fmt.Println(result) // Output: ["a", "b", "d", "e"]

func Trim added in v1.3.2

func Trim(s string, patterns ...string) string

Trim removes all leading and trailing occurrences of specified characters from the string. If no characters are provided, it removes leading and trailing whitespace.

It can be used to tidy up user input or to normalize strings for consistent processing.

The function utilizes the TrimFunc function from the standard strings package, which makes it efficient for clearing large strings.

Example usage:

g.Trim(" Hello\t World\r\n")              // Output: "Hello\t World"
g.Trim("    Go Loop   ")                  // Output: "Go Loop"
g.Trim(" i@ goloop.one ", g.Whitespaces)  // Output: "i@ goloop.one"

func Union

func Union[T comparable](a []T, b []T) []T

Union takes two slices and returns a new slice that contains all unique items from both slices. The type T must be comparable.

It removes duplicates and returns the union of the slices.

The function is generic and can work with any type T that is comparable.

Note: This function does not preserve the order of elements. The order of elements in the returned slice can be different from the order of elements in the input slices.

Example usage:

a := []int{1, 2, 3}
b := []int{3, 4, 5}
result := g.Union(a, b)
fmt.Println(result) // Output: [1 2 3 4 5]

a := []string{"a", "b", "c"}
b := []string{"c", "d", "e"}
result := g.Union(a, b)
fmt.Println(result) // Output: [a b c d e]

func VLookup

func VLookup[T comparable, U any](v T, lookup []T, result []U, def U) U

VLookup looks up and retrieves data from a specific column in a table.

The function takes a search value `v`, a slice of lookup values `lookup`, a slice of result values `result`, and an optional default value `def`. It searches for the first occurrence of `v` in the `lookup` slice and Output: the corresponding value from the `result` slice. If `v` is not found in the `lookup` slice, it returns the default value `def`.

Example usage:

// Perform a vertical lookup on a string slice and retrieve the
// corresponding value from an int slice.
lookup := []string{"A", "B", "C"}
result := []int{1, 2, 3}
val := g.VLookup("B", lookup, result, -1)
fmt.Println(val) // Output: 2

// Perform a vertical lookup on a string slice with a value that
// doesn't exist, and return the default value.
val = g.VLookup("D", lookup, result, -1)
fmt.Println(val) // Output: -1

func Value

func Value[T any](v ...T) T

Value returns the first non-zero value from the parameters.

The function checks each parameter in the order they are passed to the function and returns the first parameter that is not a zero value. If all parameters are zero values, the function returns a zero value for the type T of the parameters.

This function is generic and can work with any type T.

Example usage:

// If you want to find the first non-zero value among
// several integer variables:
a, b, c := 0, 0, 3
fmt.Println(g.Value(a, b, c)) // Output: 3

// If all values are zero, the function will return zero of the type T:
a, b, c := 0, 0, 0
fmt.Println(g.Value(a, b, c)) // Output: 0

// This function can work with any type. For example,
// if you have several string variables:
s1, s2, s3 := "", "Hello", "World"
fmt.Println(g.Value(s1, s2, s3)) // Output: Hello

// If all strings are empty (which is the zero value for strings),
// the function will return an empty string:
s1, s2, s3 := "", "", ""
fmt.Println(g.Value(s1, s2, s3)) // Output: ""

Warning: the function checks the list as the whole object, that is:

l := []int{0, 1, 2, 3}
g.Value(l)    // Returns: []int{0, 1, 2, 3}, list is not empty object
g.Value(l...) // Returns: 1, because 1 is the first not empty value

func Weed added in v1.3.2

func Weed(s string, patterns ...string) string

Weed removes characters by the patterns from the whole string.

It is a utility function that helps you to 'clean up' your strings, removing any unwanted characters (weeds). It's allegory, just as a gardener would go through a field removing any unwanted plants, this function iterates over the string and plucks out any characters specified as patterns.

By default, if no patterns are specified, it removes the most common breakers characters (e.g. newline, tab etc.). However, you can specify your own patterns to fit your needs. The function uses an efficient mapping approach to achieve this, making it effective for clearing large strings.

Example usage:

g.Weed("Hello\t World")                  // Output: "Hello World"
g.Weed(" i@ goloop.one", g.Whitespaces)  // Output: "i@goloop.one"
g.Weed("+380 (96) 123 4567", " +()")     // Output: "380961234567"

Types

type Complex added in v1.15.0

type Complex interface {
	~complex64 | ~complex128
}

Complex is a constraint that permits any complex numeric type. If future releases of Go add new predeclared complex numeric types, this constraint will be modified to include them.

type Float added in v1.15.0

type Float interface {
	~float32 | ~float64
}

Float is a constraint that permits any floating-point type. If future releases of Go add new predeclared floating-point types, this constraint will be modified to include them.

type Integer added in v1.15.0

type Integer interface {
	Signed | Unsigned
}

Integer is a constraint that permits any integer type. If future releases of Go add new predeclared integer types, this constraint will be modified to include them.

type Numerable

type Numerable interface {
	Integer | Float
}

Numerable is an interface type that is satisfied by all numeric types in Go, both integer and floating point. This includes int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, and float64. It allows functions to operate on any of these types where numerical operations such as addition, subtraction, multiplication, and division are needed. It enables generic programming techniques for numeric types.

type Ordered added in v1.15.0

type Ordered interface {
	Integer | Float | ~string
}

Ordered is a constraint that permits any ordered type: any type that supports the operators < <= >= >. If future releases of Go add new ordered types, this constraint will be modified to include them.

type Pair

type Pair[T, U any] struct {
	First  T
	Second U
}

Pair is a generic struct type with two fields: First and Second. Used as the result element of the Zip function and can contain a pair of values of any T and U types.

func Zip

func Zip[T, U any](a []T, b []U) []Pair[T, U]

Zip takes two slices and returns a slice of pairs. Each pair contains an item from each of the two slices, in the same position. The length of the returned slice is equal to the minimum of the lengths of the two input slices.

If one slice is shorter than the other, the extra elements of the longer slice are ignored.

The function returns a slice of struct where each struct has two fields: First and Second, representing the elements from the first and second slices respectively.

Example usage:

// If you have two slices of the same length:
a := []int{1, 2, 3}
b := []string{"one", "two", "three"}
pairs := g.Zip(a, b)
for _, pair := range pairs {
    fmt.Printf("(%d, %s)\n", pair.First, pair.Second)
}
// Output: (1, one) (2, two) (3, three)

// If one slice is shorter than the other:
a := []int{1, 2}
b := []string{"one", "two", "three"}
pairs := g.Zip(a, b)
for _, pair := range pairs {
    fmt.Printf("(%d, %s)\n", pair.First, pair.Second)
}
// Output: (1, one) (2, two)
// Note that the third element of the second slice is ignored.

type Signed added in v1.15.0

type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}

Signed is a constraint that permits any signed integer type. If future releases of Go add new predeclared signed integer types, this constraint will be modified to include them.

type Unsigned added in v1.15.0

type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}

Unsigned is a constraint that permits any unsigned integer type. If future releases of Go add new predeclared unsigned integer types, this constraint will be modified to include them.

type Verifiable

type Verifiable interface {
	Integer | Float | string | rune
}

Verifiable is an interface type that is satisfied by classical types like numeric types and strings in Go.

The purpose of the Verifiable interface is to enable generic programming techniques for numeric types and strings. Functions can use this interface as a constraint to operate on any of these types where numerical operations or string operations are needed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL