1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-04 12:52:28 +08:00
Files
lancet/docs/en/api/packages/slice.md
2023-09-04 11:03:22 +08:00

49 KiB

Slice

Package slice implements some functions to manipulate slice.

Source:

Usage:

import (
    "github.com/duke-git/lancet/v2/slice"
)

Index

Documentation

AppendIfAbsent

If slice doesn't contain the item, append it to the slice.

Signature:

func AppendIfAbsent[T comparable](slice []T, item T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.AppendIfAbsent([]string{"a", "b"}, "b")
    result2 := slice.AppendIfAbsent([]string{"a", "b"}, "c")

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // [a b]
    // [a b c]
}

Contain

Check if the target value is in the slice or not.

Signature:

func Contain[T comparable](slice []T, target T) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.Contain([]string{"a", "b", "c"}, "a")
    result2 := slice.Contain([]int{1, 2, 3}, 4)

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // true
    // false
}

ContainBy

returns true if predicate function return true.

Signature:

func ContainBy[T any](slice []T, predicate func(item T) bool) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    type foo struct {
        A string
        B int
    }

    array1 := []foo{{A: "1", B: 1}, {A: "2", B: 2}}
    result1 := slice.ContainBy(array1, func(f foo) bool { return f.A == "1" && f.B == 1 })
    result2 := slice.ContainBy(array1, func(f foo) bool { return f.A == "2" && f.B == 1 })

    array2 := []string{"a", "b", "c"}
    result3 := slice.ContainBy(array2, func(t string) bool { return t == "a" })
    result4 := slice.ContainBy(array2, func(t string) bool { return t == "d" })

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)
    fmt.Println(result4)

    // Output:
    // true
    // false
    // true
    // false
}

ContainSubSlice

Check if the slice contain subslice or not.

Signature:

func ContainSubSlice[T comparable](slice, subSlice []T) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "b"})
    result2 := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "d"})

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // true
    // false
}

Chunk

Creates an slice of elements split into groups the length of `size`.

Signature:

func Chunk[T any](slice []T, size int) [][]T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    arr := []string{"a", "b", "c", "d", "e"}

    result1 := slice.Chunk(arr, 1)
    result2 := slice.Chunk(arr, 2)
    result3 := slice.Chunk(arr, 3)
    result4 := slice.Chunk(arr, 4)
    result5 := slice.Chunk(arr, 5)

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)
    fmt.Println(result4)
    fmt.Println(result5)

    // Output:
    // [[a] [b] [c] [d] [e]]
    // [[a b] [c d] [e]]
    // [[a b c] [d e]]
    // [[a b c d] [e]]
    // [[a b c d e]]
}

Compact

Creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey.

Signature:

func Compact[T comparable](slice []T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.Compact([]int{0})
    result2 := slice.Compact([]int{0, 1, 2, 3})
    result3 := slice.Compact([]string{"", "a", "b", "0"})
    result4 := slice.Compact([]bool{false, true, true})

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)
    fmt.Println(result4)

    // Output:
    // []
    // [1 2 3]
    // [a b 0]
    // [true true]
}

Concat

Creates a new slice concatenating slice with any additional slices.

Signature:

func Concat[T any](slice []T, slices ...[]T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.Concat([]int{1, 2}, []int{3, 4})
    result2 := slice.Concat([]string{"a", "b"}, []string{"c"}, []string{"d"})

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // [1 2 3 4]
    // [a b c d]
}

Count

Returns the number of occurrences of the given item in the slice.

Signature:

func Count[T comparable](slice []T, item T) int

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 3, 4}

    result1 := slice.Count(nums, 1)
    result2 := slice.Count(nums, 3)

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // 1
    // 2
}

CountBy

Iterates over elements of slice with predicate function, returns the number of all matched elements.

Signature:

func CountBy[T any](slice []T, predicate func(index int, item T) bool) int

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    result := slice.CountBy(nums, isEven)

    fmt.Println(result)

    // Output:
    // 2
}

Difference

Creates an slice of whose element not included in the other given slice.

Signature:

func Difference[T comparable](slice, comparedSlice []T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    s1 := []int{1, 2, 3, 4, 5}
    s2 := []int{4, 5, 6}

    result := slice.Difference(s1, s2)

    fmt.Println(result)

    // Output:
    // [1 2 3]
}

DifferenceBy

DifferenceBy accepts iteratee func which is invoked for each element of slice and values to generate the criterion by which they're compared.

Signature:

func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    s1 := []int{1, 2, 3, 4, 5}
    s2 := []int{3, 4, 5}

    addOne := func(i int, v int) int {
        return v + 1
    }

    result := slice.DifferenceBy(s1, s2, addOne)

    fmt.Println(result)

    // Output:
    // [1 2]
}

DifferenceWith

DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice.

Signature:

func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    s1 := []int{1, 2, 3, 4, 5}
    s2 := []int{4, 5, 6, 7, 8}

    isDouble := func(v1, v2 int) bool {
        return v2 == 2*v1
    }

    result := slice.DifferenceWith(s1, s2, isDouble)

    fmt.Println(result)

    // Output:
    // [1 5]
}

DeleteAt

Delete the element of slice from start index to end index - 1.

Signature:

func DeleteAt[T any](slice []T, start int, end ...int)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.DeleteAt([]string{"a", "b", "c"}, -1)
    result2 := slice.DeleteAt([]string{"a", "b", "c"}, 0)
    result3 := slice.DeleteAt([]string{"a", "b", "c"}, 0, 2)

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)

    // Output:
    // [a b c]
    // [b c]
    // [c]
}

Drop

Drop n elements from the start of a slice.

Signature:

func Drop[T any](slice []T, n int) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.Drop([]string{"a", "b", "c"}, 0)
    result2 := slice.Drop([]string{"a", "b", "c"}, 1)
    result3 := slice.Drop([]string{"a", "b", "c"}, -1)
    result4 := slice.Drop([]string{"a", "b", "c"}, 4)

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)
    fmt.Println(result4)

    // Output:
    // [a b c]
    // [b c]
    // [a b c]
    // []
}

DropRight

Drop n elements from the end of a slice.

Signature:

func DropRight[T any](slice []T, n int) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.DropRight([]string{"a", "b", "c"}, 0)
    result2 := slice.DropRight([]string{"a", "b", "c"}, 1)
    result3 := slice.DropRight([]string{"a", "b", "c"}, -1)
    result4 := slice.DropRight([]string{"a", "b", "c"}, 4)

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)
    fmt.Println(result4)

    // Output:
    // [a b c]
    // [a b]
    // [a b c]
    // []
}

DropWhile

Drop n elements from the start of a slice while predicate function returns true.

Signature:

func DropWhile[T any](slice []T, predicate func(item T) bool) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.DropWhile(numbers, func(n int) bool {
        return n != 2
    })
    result2 := slice.DropWhile(numbers, func(n int) bool {
        return true
    })
    result3 := slice.DropWhile(numbers, func(n int) bool {
        return n == 0
    })

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)

    // Output:
    // [2 3 4 5]
    // []
    // [1 2 3 4 5]
}

DropRightWhile

Drop n elements from the end of a slice while predicate function returns true.

Signature:

func DropRightWhile[T any](slice []T, predicate func(item T) bool) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

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

    result1 := slice.DropRightWhile(numbers, func(n int) bool {
        return n != 2
    })
    result2 := slice.DropRightWhile(numbers, func(n int) bool {
        return true
    })
    result3 := slice.DropRightWhile(numbers, func(n int) bool {
        return n == 0
    })

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)

    // Output:
    // [1 2]
    // []
    // [1 2 3 4 5]
}

Equal

Check if two slices are equal: the same length and all elements' order and value are equal.

Signature:

func Equal[T comparable](slice1, slice2 []T) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    s1 := []int{1, 2, 3}
    s2 := []int{1, 2, 3}
    s3 := []int{1, 3, 2}

    result1 := slice.Equal(s1, s2)
    result2 := slice.Equal(s1, s3)

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // true
    // false
}

EqualWith

Check if two slices are equal with comparator func.

Signature:

func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    s1 := []int{1, 2, 3}
    s2 := []int{2, 4, 6}

    isDouble := func(a, b int) bool {
        return b == a*2
    }

    result := slice.EqualWith(s1, s2, isDouble)

    fmt.Println(result)

    // Output:
    // true
}

Every

Return true if all of the values in the slice pass the predicate function.

Signature:

func Every[T any](slice []T, predicate func(index int, item T) bool) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    result := slice.Every(nums, isEven)

    fmt.Println(result)

    // Output:
    // false
}

Filter

Return all elements which match the function.

Signature:

func Filter[T any](slice []T, predicate func(index int, item T) bool) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    result := slice.Filter(nums, isEven)

    fmt.Println(result)

    // Output:
    // [2 4]
}

Find(deprecated: use FindBy)

Iterates over elements of slice, returning the first one that passes a truth test on function.

Signature:

func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    result, ok := slice.Find(nums, isEven)

    fmt.Println(*result)
    fmt.Println(ok)

    // Output:
    // 2
    // true
}

FindBy

Iterates over elements of slice, returning the first one that passes a truth test on predicate function.If return T is nil or zero value then no items matched the predicate func. In contrast to Find or FindLast, its return value no longer requires dereferencing.

Signature:

func FindBy[T any](slice []T, predicate func(index int, item T) bool) (v T, ok bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    result, ok := slice.FindBy(nums, isEven)

    fmt.Println(result)
    fmt.Println(ok)

    // Output:
    // 2
    // true
}

FindLast(deprecated: use FindLastBy)

iterates over elements of slice from end to begin, returning the last one that passes a truth test on function.

Signature:

func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    result, ok := slice.FindLast(nums, isEven)

    fmt.Println(*result)
    fmt.Println(ok)

    // Output:
    // 4
    // true
}

FindLastBy

FindLastBy iterates over elements of slice, returning the last one that passes a truth test on predicate function. If return T is nil or zero value then no items matched the predicate func. In contrast to Find or FindLast, its return value no longer requires dereferencing.

Signature:

func FindLastBy[T any](slice []T, predicate func(index int, item T) bool) (v T, ok bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    result, ok := slice.FindLastBy(nums, isEven)

    fmt.Println(result)
    fmt.Println(ok)

    // Output:
    // 4
    // true
}

Flatten

Flatten slice with one level.

Signature:

func Flatten(slice any) any

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    arrs := [][][]string{{{"a", "b"}}, {{"c", "d"}}}

    result := slice.Flatten(arrs)

    fmt.Println(result)

    // Output:
    // [[a b] [c d]]
}

FlattenDeep

flattens slice recursive.

Signature:

func FlattenDeep(slice any) any

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    arrs := [][][]string{{{"a", "b"}}, {{"c", "d"}}}

    result := slice.FlattenDeep(arrs)

    fmt.Println(result)

    // Output:
    // [a b c d]
}

ForEach

Iterates over elements of slice and invokes function for each element.

Signature:

func ForEach[T any](slice []T, iteratee func(index int, item T))

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3}

    var result []int
    addOne := func(_ int, v int) {
        result = append(result, v+1)
    }

    slice.ForEach(nums, addOne)

    fmt.Println(result)

    // Output:
    // [2 3 4]
}

ForEachWithBreak

Iterates over elements of slice and invokes function for each element, when iteratee return false, will break the for each loop.

Signature:

func ForEachWithBreak[T any](slice []T, iteratee func(index int, item T) bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

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

    var sum int

    slice.ForEachWithBreak(numbers, func(_, n int) bool {
        if n > 3 {
            return false
        }
        sum += n
        return true
    })

    fmt.Println(sum)

    // Output:
    // 6
}

GroupBy

Iterates over elements of the slice, each element will be group by criteria, returns two slices.

Signature:

func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    even, odd := slice.GroupBy(nums, isEven)

    fmt.Println(even)
    fmt.Println(odd)

    // Output:
    // [2 4]
    // [1 3 5]
}

GroupWith

Return a map composed of keys generated from the results of running each element of slice thru iteratee.

Signature:

func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []float64{6.1, 4.2, 6.3}

    floor := func(num float64) float64 {
        return math.Floor(num)
    }

    result := slice.GroupWith(nums, floor) //map[float64][]float64

    fmt.Println(result)

    // Output:
    // map[4:[4.2] 6:[6.1 6.3]]
}

IntSlice (Deprecated: use generic feature of go1.18+ for replacement)

Convert interface slice to int slice.

Signature:

func IntSlice(slice any) []int

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []interface{}{1, 2, 3}

    result := slice.IntSlice(nums) //[]int{1, 2, 3}
    fmt.Println(result)

    // Output:
    // [1 2 3]
}

InterfaceSlice (Deprecated: use generic feature of go1.18+ for replacement)

Convert value to interface slice.

Signature:

func InterfaceSlice(slice any) []any

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    strs := []string{"a", "b", "c"}

    result := slice.InterfaceSlice(strs) //[]interface{}{"a", "b", "c"}
    fmt.Println(result)

    // Output:
    // [a b c]
}

Intersection

Creates a slice of unique values that included by all slices.

Signature:

func Intersection[T comparable](slices ...[]T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums1 := []int{1, 2, 3}
    nums2 := []int{2, 3, 4}

    result := slice.Intersection(nums1, nums2)

    fmt.Println(result)

    // Output:
    // [2 3]
}

InsertAt

insert the element into slice at index.

Signature:

func InsertAt[T any](slice []T, index int, value any) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.InsertAt([]string{"a", "b", "c"}, 0, "1")
    result2 := slice.InsertAt([]string{"a", "b", "c"}, 1, "1")
    result3 := slice.InsertAt([]string{"a", "b", "c"}, 2, "1")
    result4 := slice.InsertAt([]string{"a", "b", "c"}, 3, "1")
    result5 := slice.InsertAt([]string{"a", "b", "c"}, 0, []string{"1", "2", "3"})

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)
    fmt.Println(result4)
    fmt.Println(result5)

    // Output:
    // [1 a b c]
    // [a 1 b c]
    // [a b 1 c]
    // [a b c 1]
    // [1 2 3 a b c]
}

IndexOf

Returns the index at which the first occurrence of a item is found in a slice or return -1 if the item cannot be found.

Signature:

func IndexOf[T comparable](slice []T, item T) int

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    strs := []string{"a", "a", "b", "c"}

    result1 := slice.IndexOf(strs, "a")
    result2 := slice.IndexOf(strs, "d")

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // 0
    // -1
}

LastIndexOf

Returns the index at which the last occurrence of a item is found in a slice or return -1 if the item cannot be found.

Signature:

func LastIndexOf[T comparable](slice []T, item T) int

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    strs := []string{"a", "a", "b", "c"}

    result1 := slice.LastIndexOf(strs, "a")
    result2 := slice.LastIndexOf(strs, "d")

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // 1
    // -1
}

Map

Creates an slice of values by running each element in slice thru function.

Signature:

func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3}

    addOne := func(_ int, v int) int {
        return v + 1
    }

    result := slice.Map(nums, addOne)

    fmt.Println(result)

    // Output:
    // [2 3 4]
}

FilterMap

Returns a slice which apply both filtering and mapping to the given slice. iteratee callback function should returntwo values: 1, mapping result. 2, whether the result element should be included or not.

Signature:

func FilterMap[T any, U any](slice []T, iteratee func(index int, item T) (U, bool)) []U

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    getEvenNumStr := func(i, num int) (string, bool) {
        if num%2 == 0 {
            return strconv.FormatInt(int64(num), 10), true
        }
        return "", false
    }

    result := slice.FilterMap(nums, getEvenNumStr)

    fmt.Printf("%#v", result)

    // Output:
    // []string{"2", "4"}
}

FlatMap

Manipulates a slice and transforms and flattens it to a slice of another type.

Signature:

func FlatMap[T any, U any](slice []T, iteratee func(index int, item T) []U) []U

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4}

    result := slice.FlatMap(nums, func(i int, num int) []string {
        s := "hi-" + strconv.FormatInt(int64(num), 10)
        return []string{s}
    })

    fmt.Printf("%#v", result)

    // Output:
    // []string{"hi-1", "hi-2", "hi-3", "hi-4"}
}

Merge

Merge all given slices into one slice.

Signature:

func Merge[T any](slices ...[]T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums1 := []int{1, 2, 3}
    nums2 := []int{3, 4}

    result := slice.Merge(nums1, nums2)

    fmt.Println(result)

    // Output:
    // [1 2 3 3 4]
}

Reverse

Reverse the elements order in slice.

Signature:

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

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    strs := []string{"a", "b", "c", "d"}

    slice.Reverse(strs)

    fmt.Println(strs)

    // Output:
    // [d c b a]
}

Reduce

Reduce slice.(Deprecated: use ReduceBy)

Signature:

func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3}

    sum := func(_ int, v1, v2 int) int {
        return v1 + v2
    }

    result := slice.Reduce(nums, sum, 0)

    fmt.Println(result)

    // Output:
    // 6
}

ReduceBy

Produces a value from slice by accumulating the result of each element as passed through the reducer function.

Signature:

func ReduceBy[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.ReduceBy([]int{1, 2, 3, 4}, 0, func(_ int, item int, agg int) int {
        return agg + item
    })

    result2 := slice.ReduceBy([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string {
        return agg + fmt.Sprintf("%v", item)
    })

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // 10
    // 1234
}

ReduceRight

ReduceRight is like ReduceBy, but it iterates over elements of slice from right to left.

Signature:

func ReduceRight[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result := slice.ReduceRight([]int{1, 2, 3, 4}, "", func(_ int, item int, agg string) string {
        return agg + fmt.Sprintf("%v", item)
    })

    fmt.Println(result)

    // Output:
    // 4321
}

Replace

Returns a copy of the slice with the first n non-overlapping instances of old replaced by new.

Signature:

func Replace[T comparable](slice []T, old T, new T, n int) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    strs := []string{"a", "b", "c", "a"}

    result1 := slice.Replace(strs, "a", "x", 0)
    result2 := slice.Replace(strs, "a", "x", 1)
    result3 := slice.Replace(strs, "a", "x", 2)
    result4 := slice.Replace(strs, "a", "x", 3)
    result5 := slice.Replace(strs, "a", "x", -1)

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)
    fmt.Println(result4)
    fmt.Println(result5)

    // Output:
    // [a b c a]
    // [x b c a]
    // [x b c x]
    // [x b c x]
    // [x b c x]
}

ReplaceAll

Returns a copy of the slice with the first n non-overlapping instances of old replaced by new.

Signature:

func ReplaceAll[T comparable](slice []T, old T, new T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result := slice.ReplaceAll([]string{"a", "b", "c", "a"}, "a", "x")

    fmt.Println(result)

    // Output:
    // [x b c x]
}

Repeat

Creates a slice with length n whose elements are passed param item.

Signature:

func Repeat[T any](item T, n int) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result := slice.Repeat("a", 3)

    fmt.Println(result)

    // Output:
    // [a a a]
}

Shuffle

Creates an slice of shuffled values.

Signature:

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

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}
    result := slice.Shuffle(nums)

    fmt.Println(res)

    // Output:
    // [3 1 5 4 2] (random order)
}

IsAscending

Checks if a slice is ascending order.

Signature:

func IsAscending[T constraints.Ordered](slice []T) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.IsAscending([]int{1, 2, 3, 4, 5})
    result2 := slice.IsAscending([]int{5, 4, 3, 2, 1})
    result3 := slice.IsAscending([]int{2, 1, 3, 4, 5})

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)

    // Output:
    // true
    // false
    // false
}

IsDescending

Checks if a slice is descending order.

Signature:

func IsDescending[T constraints.Ordered](slice []T) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.IsDescending([]int{5, 4, 3, 2, 1})
    result2 := slice.IsDescending([]int{1, 2, 3, 4, 5})
    result3 := slice.IsDescending([]int{2, 1, 3, 4, 5})

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)

    // Output:
    // true
    // false
    // false
}

IsSorted

Checks if a slice is sorted (ascending or descending).

Signature:

func IsSorted[T constraints.Ordered](slice []T) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.IsSorted([]int{5, 4, 3, 2, 1})
    result2 := slice.IsSorted([]int{1, 2, 3, 4, 5})
    result3 := slice.IsSorted([]int{2, 1, 3, 4, 5})

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)

    // Output:
    // true
    // true
    // false
}

IsSortedByKey

Checks if a slice is sorted by iteratee function.

Signature:

func IsSortedByKey[T any, K constraints.Ordered](slice []T, iteratee func(item T) K) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.IsSortedByKey([]string{"a", "ab", "abc"}, func(s string) int {
        return len(s)
    })
    result2 := slice.IsSortedByKey([]string{"abc", "ab", "a"}, func(s string) int {
        return len(s)
    })
    result3 := slice.IsSortedByKey([]string{"abc", "a", "ab"}, func(s string) int {
        return len(s)
    })

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)

    // Output:
    // true
    // true
    // false
}

Sort

Sorts a slice of any ordered type(number or string), use quick sort algrithm. Default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`. Ordered type: number(all ints uints floats) or string.

Signature:

func Sort[T constraints.Ordered](slice []T, sortOrder ...string)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

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

    slice.Sort(numbers)
    fmt.Println(numbers) // [1 2 3 4 5]

    slice.Sort(numbers, "desc")
    fmt.Println(numbers) // [5 4 3 2 1]

    strings := []string{"a", "d", "c", "b", "e"}

    slice.Sort(strings)
    fmt.Println(strings) //[a b c d e}

    slice.Sort(strings, "desc")
    fmt.Println(strings) //[e d c b a]
}

SortBy

Sorts the slice in ascending order as determined by the less function. This sort is not guaranteed to be stable.

Signature:

func SortBy[T any](slice []T, less func(a, b T) bool)

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

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

    slice.SortBy(numbers, func(a, b int) bool {
        return a < b
    })
    fmt.Println(numbers) // [1 2 3 4 5]

    type User struct {
        Name string
        Age  uint
    }

    users := []User{
        {Name: "a", Age: 21},
        {Name: "b", Age: 15},
        {Name: "c", Age: 100}}

    slice.SortBy(users, func(a, b User) bool {
        return a.Age < b.Age
    })

    fmt.Printf("sort users by age: %v", users)

    // output
    // [{b 15} {a 21} {c 100}]
}

SortByField

Sort struct slice by field. Slice element should be struct, `field` param type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set `sortType` param to desc.

Signature:

func SortByField(slice any, field string, sortType ...string) error

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    type User struct {
        Name string
        Age  uint
    }

    users := []User{
        {Name: "a", Age: 21},
        {Name: "b", Age: 15},
        {Name: "c", Age: 100}}

    err := slice.SortByField(users, "Age", "desc")
    if err != nil {
        return
    }

    fmt.Println(users)

    // Output:
    // [{c 100} {a 21} {b 15}]
}

Some

Return true if any of the values in the list pass the predicate function.

Signature:

func Some[T any](slice []T, predicate func(index int, item T) bool) bool

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 5}

    isEven := func(i, num int) bool {
        return num%2 == 0
    }

    result := slice.Some(nums, isEven)

    fmt.Println(result)

    // Output:
    // true
}

StringSlice (Deprecated: use generic feature of go1.18+ for replacement)

Convert interface slice to string slice.

Signature:

func StringSlice(slice any) []string

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    strs := []interface{}{"a", "b", "c"}

    result := slice.StringSlice(strs) //[]string{"a", "b", "c"}
    fmt.Println(result)

    // Output:
    // [a b c]
}

SymmetricDifference

Create a slice whose element is in given slices, but not in both slices.

Signature:

func SymmetricDifference[T comparable](slices ...[]T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums1 := []int{1, 2, 3}
    nums2 := []int{1, 2, 4}

    result := slice.SymmetricDifference(nums1, nums2)

    fmt.Println(result)

    // Output:
    // [3 4]
}

ToSlice

Creates a slice of give items.

Signature:

func ToSlice[T any](items ...T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result := slice.ToSlice("a", "b", "c")

    fmt.Println(result)

    // Output:
    // [a b c]
}

ToSlicePointer

Returns a pointer to the slices of a variable parameter transformation

Signature:

func ToSlicePointer[T any](items ...T) []*T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    str1 := "a"
    str2 := "b"

    result := slice.ToSlicePointer(str1, str2)

    expect := []*string{&str1, &str2}

    isEqual := reflect.DeepEqual(result, expect)

    fmt.Println(isEqual)

    // Output:
    // true
}

Unique

Remove duplicate elements in slice.

Signature:

func Unique[T comparable](slice []T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result := slice.Unique([]string{"a", "a", "b"})
    fmt.Println(result)

    // Output:
    // [a b]
}

UniqueBy

Call iteratee func with every item of slice, then remove duplicated.

Signature:

func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5, 6}
    result := slice.UniqueBy(nums, func(val int) int {
        return val % 3
    })

    fmt.Println(result)

    // Output:
    // [1 2 0]
}

Union

Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.

Signature:

func Union[T comparable](slices ...[]T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums1 := []int{1, 3, 4, 6}
    nums2 := []int{1, 2, 5, 6}

    result := slice.Union(nums1, nums2)

    fmt.Println(result)

    // Output:
    // [1 3 4 6 2 5]
}

UnionBy

UnionBy is like Union, what's more it accepts iteratee which is invoked for each element of each slice.

Signature:

func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4}

    divideTwo := func(n int) int {
        return n / 2
    }
    result := slice.UnionBy(divideTwo, nums)

    fmt.Println(result)

    // Output:
    // [1 2 4]
}

UpdateAt

Update the slice element at index. if param index < 0 or index <= len(slice), will return error.

Signature:

func UpdateAt[T any](slice []T, index int, value T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result1 := slice.UpdateAt([]string{"a", "b", "c"}, -1, "1")
    result2 := slice.UpdateAt([]string{"a", "b", "c"}, 0, "1")
    result3 := slice.UpdateAt([]string{"a", "b", "c"}, 1, "1")
    result4 := slice.UpdateAt([]string{"a", "b", "c"}, 2, "1")
    result5 := slice.UpdateAt([]string{"a", "b", "c"}, 3, "1")

    fmt.Println(result1)
    fmt.Println(result2)
    fmt.Println(result3)
    fmt.Println(result4)
    fmt.Println(result5)

    // Output:
    // [a b c]
    // [1 b c]
    // [a 1 c]
    // [a b 1]
    // [a b c]
}

Without

Creates a slice excluding all given items.

Signature:

func Without[T comparable](slice []T, items ...T) []T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result := slice.Without([]int{1, 2, 3, 4}, 1, 2)

    fmt.Println(result)

    // Output:
    // [3 4]
}

KeyBy

Converts a slice to a map based on a callback function.

Signature:

func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    result := slice.KeyBy([]string{"a", "ab", "abc"}, func(str string) int {
        return len(str)
    })

    fmt.Println(result)

    // Output:
    // map[1:a 2:ab 3:abc]
}

Join

Join the slice item with specify separator.

Signature:

func Join[T any](s []T, separator string) string

Example:Run

import (
    "fmt"
    "github.com/duke-git/lancet/v2/slice"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    result1 := slice.Join(nums, ",")
    result2 := slice.Join(nums, "-")

    fmt.Println(result1)
    fmt.Println(result2)

    // Output:
    // 1,2,3,4,5
    // 1-2-3-4-5
}