Go lancet
last modified April 11, 2024
In this article we show how to work with the lancet utility library.
Lancet
Lancet is a comprehensive, efficient, and reusable utility function library for the Go programming language. It contains over 600 functions. Lancet covers various areas including strings, slices, datetimes, net, zip, system, tuples, or data structures.
System functions
In the system package, we have some system-related functions.
package main import ( "fmt" "github.com/duke-git/lancet/v2/system" ) func main() { res := system.GetOsEnv("JAVA_HOME") fmt.Println(res) fmt.Println("----------------------------") stdout, stderr, err := system.ExecCommand("ls") fmt.Println(stdout) fmt.Println(stderr) fmt.Println(err) fmt.Println("----------------------------") if system.IsLinux() { fmt.Println("OS is Linux") } else if system.IsWindows() { fmt.Println("OS is Windows") } else if system.IsMac() { fmt.Println("OS is Mac") } else { fmt.Println("Unknown OS") } }
The example retrieves an environment variable, runs a command, and determines the OS.
res := system.GetOsEnv("JAVA_HOME") fmt.Println(res)
With GetOsEnv
function, we retrieve the JAVA_HOME
directory if present.
stdout, stderr, err := system.ExecCommand("ls")
We launch the ls
command with ExecCommand
.
if system.IsLinux() { fmt.Println("OS is Linux") } else if system.IsWindows() { fmt.Println("OS is Windows") } else if system.IsMac() { fmt.Println("OS is Mac") } else { fmt.Println("Unknown OS") }
We check the running OS with IsLinux
, IsWindows
, and
IsMac
functions.
$ go run main.go C:\Users\Jano\.jdks\coretto-17.0.7_7 ---------------------------- Directory: C:\Users\Jano\Documents\prog\go\lancet\system Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 23. 9. 2023 15:26 167 go.mod -a---- 23. 9. 2023 15:26 2941 go.sum -a---- 23. 9. 2023 15:27 596 main.go <nil> ------------------ OS is Windows
Tuple functions
Lancet has support for tuples.
package main import ( "fmt" "github.com/duke-git/lancet/v2/tuple" ) func main() { t := tuple.NewTuple2(1, 0.1) x, y := t.Unbox() fmt.Println(x) fmt.Println(y) fmt.Printf("%v %v", t.FieldA, t.FieldB) t2 := tuple.NewTuple3(1, 0.1, "a") fmt.Printf("%v %v %v", t2.FieldA, t2.FieldB, t2.FieldC) a, b, c := t2.Unbox() fmt.Println(a) fmt.Println(b) fmt.Println(c) }
The example defines and unboxes two-element and three-elements tuples.
$ go run main.go 1 0.1 1 0.11 0.1 a1 0.1 a
Date and time functions
In the datetime
package, we have functions related to date and
time.
package main import ( "fmt" "time" "github.com/duke-git/lancet/v2/datetime" ) func main() { now := time.Now() dt := datetime.AddYear(now, 11) fmt.Println(dt) fmt.Println(datetime.FormatTimeToStr(dt, "yyyy-mm-dd")) res2 := datetime.EndOfYear(now) fmt.Println(res2) begin := datetime.BeginOfWeek(now) fmt.Println(begin) }
The example presents the AddYear
, FormatTimeToStr
,
EndOfYear
, and BeginOfWeek
functions.
$ go run main.go 2034-09-20 15:45:35.7624076 +0200 CEST m=+346896000.002289001 2034-09-20 2023-12-31 23:59:59.999999999 +0100 CET 2023-09-17 00:00:00 +0200 CEST
Slice functions
In the next example we present some slice functions.
package main import ( "fmt" "github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/v2/strutil" ) func main() { vals := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} isEven := func(i, num int) bool { return num%2 == 0 } n1 := slice.CountBy(vals, isEven) fmt.Println(n1) words := []string{"sky", "war", "blue", "war", "cottage", "war", "car", "pen", "book"} n2 := slice.Count(words, "war") fmt.Println(n2) fmt.Println("------------------------------") shuffled := slice.Shuffle(vals) slice.ForEach(shuffled, func(_, e int) { fmt.Println(e) }) fmt.Println("------------------------------") res := slice.Map(vals, func(_, e int) int { return e * 2 }) fmt.Println(res) res2 := slice.Map(words, func(_ int, e string) string { return strutil.UpperFirst(e) }) fmt.Println(res2) }
The example uses the CountBy
, Count
,
Shuffle
, Map
, and ForEach
slice
functions.
vals := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} isEven := func(i, num int) bool { return num%2 == 0 } n1 := slice.CountBy(vals, isEven)
With CountBy
, we count the number of slice elements for which the
isEven
predicate returns true.
words := []string{"sky", "war", "blue", "war", "cottage", "war", "car", "pen", "book"} n2 := slice.Count(words, "war")
We count the number of occurrences for the war
word in the
words
slice.
shuffled := slice.Shuffle(vals) slice.ForEach(shuffled, func(_, e int) { fmt.Println(e) })
We randonly rearrange the vals
slice with Shuffle
and
iterate over it with ForEach
.
res := slice.Map(vals, func(_, e int) int { return e * 2 }) fmt.Println(res)
With Map
, we apply the given anonymous function to each element of
the slice.
$ go run main.go 5 3 ------------------------------ 6 10 11 9 7 2 1 5 3 4 8 ------------------------------ [12 20 22 18 14 4 2 10 6 8 16] [Sky War Blue War Cottage War Car Pen Book]
Net functions
We have a couple net-related functions.
package main import ( "fmt" "log" "github.com/duke-git/lancet/v2/netutil" ) type Post struct { UserId int `json:"userId"` Id int `json:"id"` Title string `json:"title"` Body string `json:"body"` } func main() { req := &netutil.HttpRequest{ RawURL: "https://jsonplaceholder.typicode.com/posts/1", Method: "GET", } client := netutil.NewHttpClient() resp, err := client.SendRequest(req) if err != nil || resp.StatusCode != 200 { log.Fatal(err) } var body Post err = client.DecodeResponse(resp, &body) if err != nil { log.Fatal(err) } fmt.Println(body) fmt.Println("-------------------------") fmt.Println(body.Id) fmt.Println(body.UserId) fmt.Println(body.Title) fmt.Println(body.Body) }
The example retrieves a post from an online test service.
req := &netutil.HttpRequest{ RawURL: "https://jsonplaceholder.typicode.com/posts/1", Method: "GET", }
We define an HTTP GET request.
client := netutil.NewHttpClient() resp, err := client.SendRequest(req)
An HTTP client is created and a new request is sent.
if err != nil || resp.StatusCode != 200 { log.Fatal(err) }
We check for the response status and error.
var body Post err = client.DecodeResponse(resp, &body) if err != nil { log.Fatal(err) }
We decode the JSON response into the Post struct body.
Sorting functions
The algorithm
package contains a few sorting algorithms.
In the next example, we use the quick sort algorithm.
package main import ( "fmt" "github.com/duke-git/lancet/v2/algorithm" ) type intComparator struct{} func (c *intComparator) Compare(e1 any, e2 any) int { val1, _ := e1.(int) val2, _ := e2.(int) if val1 < val2 { return -1 } else if val1 > val2 { return 1 } return 0 } func main() { vals := []int{2, 1, 5, 3, 6, 4, -2, 0, 9, 11, -3} comparator := &intComparator{} algorithm.QuickSort(vals, comparator) fmt.Println(vals) }
The example uses the quick sort algorithm to sort integers in a slice.
type intComparator struct{} func (c *intComparator) Compare(e1 any, e2 any) int { val1, _ := e1.(int) val2, _ := e2.(int) if val1 < val2 { return -1 } else if val1 > val2 { return 1 } return 0 }
We define the Compare
function.
comparator := &intComparator{} algorithm.QuickSort(vals, comparator)
We compare the numbers with QuickSort
.
$ go run main.go [-3 -2 0 1 2 3 4 5 6 9 11]
The following example uses the insertion sort algorithm.
package main import ( "fmt" "github.com/duke-git/lancet/v2/algorithm" ) type User struct { Name string Age int } type byAge struct{} func (c *byAge) Compare(u1 any, u2 any) int { p1, _ := u1.(User) p2, _ := u2.(User) if p1.Age < p2.Age { return -1 } else if p1.Age > p2.Age { return 1 } return 0 } func main() { users := []User{ {Name: "Peter", Age: 20}, {Name: "Julia", Age: 14}, {Name: "Lucia", Age: 17}, {Name: "Roman", Age: 18}, {Name: "Jan", Age: 28}, } comparator := &byAge{} algorithm.InsertionSort(users, comparator) fmt.Println(users) }
The example sorts the users by their age using InsertionSort
.
func (pc *byAge) Compare(u1 any, u2 any) int { p1, _ := u1.(User) p2, _ := u2.(User) if p1.Age < p2.Age { return -1 } else if p1.Age > p2.Age { return 1 } return 0 }
We define the Compare
function.
comparator := &byAge{} algorithm.InsertionSort(users, comparator)
We sort the users in-place with InsertionSort
.
$ go run main.go [{Julia 14} {Lucia 17} {Roman 18} {Peter 20} {Jan 28}]
String functions
String functions are located in the strutil
package.
package main import ( "fmt" "github.com/duke-git/lancet/v2/strutil" ) func main() { msg := "an old falcon" fmt.Println(strutil.CamelCase(msg)) fmt.Println(strutil.Capitalize(msg)) fmt.Println(strutil.KebabCase(msg)) fmt.Println(strutil.UpperFirst(msg)) fmt.Println(strutil.SnakeCase(msg)) fmt.Println(strutil.Reverse(msg)) }
The example modifies a string with six various functions.
$ go run main.go anOldFalcon An old falcon an-old-falcon An old falcon an_old_falcon noclaf dlo na
Next we use another 4 functions.
package main import ( "fmt" "github.com/duke-git/lancet/v2/strutil" ) func main() { msg := "F# мультипарадигмальный язык программирования из семейства языков .NET." fmt.Println(strutil.WordCount(msg)) fmt.Println(strutil.IsString(msg)) w1 := "\t" w2 := " " w3 := "." fmt.Println(strutil.IsBlank(w1)) fmt.Println(strutil.IsBlank(w2)) fmt.Println(strutil.IsBlank(w3)) fmt.Println(strutil.IsBlank(strutil.Trim(w1))) }
In the next example, we count words in a string and check values with
IsString
and IsBlank
, and trim a string with
Trim
.
$ go run main.go 8 true true true false true
The function package
The function
package can control the flow of function execution and
provides some support for functional programming.
package main import ( "fmt" "github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/v2/slice" ) func double(vals []int) []int { return slice.Map(vals, func(_, e int) int { return e * 2 }) } func incByOne(vals []int) []int { return slice.Map(vals, func(_, e int) int { return e + 1 }) } func main() { vals := []int{1, 2, 3, 4, 5} transform := function.Pipeline(double, incByOne) res := transform(vals) fmt.Println(res) }
In the example, we call Pipeline
to pipe two functions on the
vals
slice.
func double(vals []int) []int { return slice.Map(vals, func(_, e int) int { return e * 2 }) } func incByOne(vals []int) []int { return slice.Map(vals, func(_, e int) int { return e + 1 }) }
We have two functions that double and increment the slice elements.
transform := function.Pipeline(double, incByOne)
We create a pipeline consisting of these two functions.
res := transform(vals)
The pipeline is executed.
$ go run main.go [3 5 7 9 11]
Zip
The fileutil
package contains a Zip
function, which
creates a ZIP archive.
package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.Zip(".", "current.zip") if err != nil { fmt.Println(err) } }
The example creates a ZIP archive from the current working directory.
Source
In this article we have worked with lancet utility library.
Author
List all Go tutorials.