Slice
slice 包包含操作切片的方法集合。
源码:
- https://github.com/duke-git/lancet/blob/main/slice/slice.go
- https://github.com/duke-git/lancet/blob/main/slice/slice_concurrent.go
用法:
import (
"github.com/duke-git/lancet/v2/slice"
)
目录
- AppendIfAbsent
- Contain
- ContainBy
- ContainSubSlice
- Chunk
- Compact
- Concat
- Count
- CountBy
- Difference
- DifferenceBy
- DifferenceWith
- DeleteAt
- DeleteRange
- Drop
- DropRight
- DropWhile
- DropRightWhile
- Every
- Equal
- EqualWith
- Filter
- FilterConcurrent
- Finddeprecated
- FindBy
- FindLastdeprecated
- FindLastBy
- Flatten
- FlattenDeep
- ForEach
- ForEachConcurrent
- ForEachWithBreak
- GroupBy
- GroupWith
- IntSlicedeprecated
- InterfaceSlicedeprecated
- Intersection
- InsertAt
- IndexOf
- LastIndexOf
- Map
- MapConcurrent
- FilterMap
- FlatMap
- Merge
- Reverse
- Reducedeprecated
- ReduceConcurrent
- ReduceBy
- ReduceRight
- Replace
- ReplaceAll
- Repeat
- Shuffle
- IsAscending
- IsDescending
- IsSorted
- IsSortedByKey
- Sort
- SortBy
- SortByField
- Some
- StringSlicedeprecated
- SymmetricDifference
- ToSlice
- ToSlicePointer
- Unique
- UniqueBy
- UniqueByComparator
- UniqueByField
- UniqueByConcurrent
- Union
- UnionBy
- UpdateAt
- Without
- KeyBy
- Join
- Partition
- SetToDefaultIf
- Break
- RightPadding
- LeftPadding
- Frequency
文档
AppendIfAbsent
当前切片中不包含值时,将该值追加到切片中
函数签名:
func AppendIfAbsent[T comparable](slice []T, item T) []T
示例:运行
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
判断slice是否包含value
函数签名:
func Contain[T comparable](slice []T, target T) bool
示例:运行
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
根据predicate函数判断切片是否包含某个值。
函数签名:
func ContainBy[T any](slice []T, predicate func(item T) bool) bool
示例:运行
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
判断slice是否包含subslice
函数签名:
func ContainSubSlice[T comparable](slice, subSlice []T) bool
示例:运行
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
按照size参数均分slice
函数签名:
func Chunk[T any](slice []T, size int) [][]T
示例:运行
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
去除slice中的假值(false values are false, nil, 0, "")
函数签名:
func Compact[T comparable](slice []T) []T
示例:运行
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
创建一个新的切片,将传入的切片拼接起来返回。
函数签名:
func Concat[T any](slices ...[]T) []T
示例:运行
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
返回切片中指定元素的个数
函数签名:
func Count[T comparable](slice []T, item T) int
示例:运行
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
遍历切片,对每个元素执行函数predicate. 返回符合函数返回值为true的元素的个数.
函数签名:
func CountBy[T any](slice []T, predicate func(index int, item T) bool) int
示例:运行
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
创建一个切片,其元素不包含在另一个给定切片中
函数签名:
func Difference[T comparable](slice, comparedSlice []T) []T
示例:运行
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
将两个slice中的每个元素调用iteratee函数,并比较它们的返回值,如果不相等返回在slice中对应的值
函数签名:
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T
示例:运行
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
接受比较器函数,该比较器被调用以将切片的元素与值进行比较。 结果值的顺序和引用由第一个切片确定
函数签名:
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T
示例:运行
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
删除切片中指定索引的元素(不修改原切片)。
函数签名:
func DeleteAt[T any](slice []T, index int) []T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
chars := []string{"a", "b", "c", "d", "e"}
result1 := slice.DeleteAt(chars, 0)
result2 := slice.DeleteAt(chars, 4)
result3 := slice.DeleteAt(chars, 5)
result4 := slice.DeleteAt(chars, 6)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// [b c d e]
// [a b c d]
// [a b c d]
// [a b c d]
}
DeleteRange
删除切片中指定索引范围的元素(不修改原切片)。
函数签名:
func DeleteRange[T any](slice []T, start, end int) []T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
chars := []string{"a", "b", "c", "d", "e"}
result1 := DeleteRange(chars, 0, 0)
result2 := DeleteRange(chars, 0, 1)
result3 := DeleteRange(chars, 0, 3)
result4 := DeleteRange(chars, 0, 4)
result5 := DeleteRange(chars, 0, 5)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// [a b c d e]
// [b c d e]
// [d e]
// [e]
// []
}
Drop
从切片的头部删除n个元素。
函数签名:
func Drop[T any](slice []T, n int) []T
示例:运行
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
从切片的尾部删除n个元素。
函数签名:
func DropRight[T any](slice []T, n int) []T
示例:运行
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
从切片的头部删除n个元素,这个n个元素满足predicate函数返回true。
函数签名:
func DropWhile[T any](slice []T, predicate func(item T) bool) []T
示例:运行
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
从切片的尾部删除n个元素,这个n个元素满足predicate函数返回true。
函数签名:
func DropRightWhile[T any](slice []T, predicate func(item T) bool) []T
示例:运行
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]
}
Every
如果切片中的所有值都通过谓词函数,则返回true。 函数签名应该是func(index int, value any) bool
函数签名:
func Every[T any](slice []T, predicate func(index int, item T) bool) bool
示例:运行
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
}
Equal
检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同
函数签名:
func Equal[T comparable](slice1, slice2 []T) bool
示例:运行
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
检查两个切片是否相等,相等条件:对两个切片的元素调用比较函数comparator,返回true
函数签名:
func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) bool
示例:运行
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
}
Filter
返回切片中通过predicate函数真值测试的所有元素
函数签名:
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T
示例:运行
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]
}
FilterConcurrent
对slice并发执行filter操作。
函数签名:
func FilterConcurrent[T any](slice []T, predicate func(index int, item T) bool, numThreads int) []T
示例:运行
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.FilterConcurrent(nums, isEven, 2)
fmt.Println(result)
// Output:
// [2 4]
}
Find
遍历slice的元素,返回第一个通过predicate函数真值测试的元素
⚠️ 本函数已弃用,使用
FindBy
代替。
函数签名:
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
示例:运行
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
遍历slice的元素,返回第一个通过predicate函数真值测试的元素
函数签名:
func FindBy[T any](slice []T, predicate func(index int, item T) bool) (v T, ok bool)
示例:运行
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
遍历slice的元素,返回最后一个通过predicate函数真值测试的元素。
⚠️ 本函数已弃用,使用
FindLastBy
代替。
函数签名:
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool)
示例:运行
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
从遍历slice的元素,返回最后一个通过predicate函数真值测试的元素。
函数签名:
func FindLastBy[T any](slice []T, predicate func(index int, item T) bool) (v T, ok bool)
示例:运行
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
将切片压平一层
函数签名:
func Flatten(slice any) any
示例:运行
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.
函数签名:
func FlattenDeep(slice any) any
示例:运行
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
遍历切片的元素并为每个元素调用iteratee函数
函数签名:
func ForEach[T any](slice []T, iteratee func(index int, item T))
示例:运行
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]
}
ForEachConcurrent
对slice并发执行foreach操作。
函数签名:
func ForEachConcurrent[T any](slice []T, iteratee func(index int, item T), numThreads int)
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5, 6, 7, 8}
result := make([]int, len(nums))
addOne := func(index int, value int) {
result[index] = value + 1
}
slice.ForEachConcurrent(nums, addOne, 4)
fmt.Println(result)
// Output:
// [2 3 4 5 6 7 8 9]
}
ForEachWithBreak
遍历切片的元素并为每个元素调用iteratee函数,当iteratee函数返回false时,终止遍历。
函数签名:
func ForEachWithBreak[T any](slice []T, iteratee func(index int, item T) bool)
示例:运行
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
迭代切片的元素,每个元素将按条件分组,返回两个切片
函数签名:
func GroupBy[T any](slice []T, groupFn func(index int, item T) bool) ([]T, []T)
示例:运行
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
创建一个map,key是iteratee遍历slice中的每个元素返回的结果。 分组值的顺序是由他们出现在slice中的顺序确定的。每个键对应的值负责生成key的元素组成的数组。iteratee调用1个参数: (value)
函数签名:
func GroupWith[T any, U comparable](slice []T, iteratee func(T) U) map[U][]T
示例:运行
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
将接口切片转换为int切片
⚠️ 本函数已弃用,使用go1.18+泛型代替。
函数签名:
func IntSlice(slice any) []int
示例:运行
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
将值转换为接口切片
⚠️ 本函数已弃用,使用go1.18+泛型代替。
函数签名:
func InterfaceSlice(slice any) []any
示例:运行
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
多个切片的交集
函数签名:
func Intersection[T comparable](slices ...[]T) []T
示例:运行
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
将元素插入到索引处的切片中
函数签名:
func InsertAt[T any](slice []T, index int, value any) []T
示例:运行
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
返回在切片中找到值的第一个匹配项的索引,如果找不到值,则返回-1
函数签名:
func IndexOf[T comparable](slice []T, item T) int
示例:运行
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
返回在切片中找到最后一个值的索引,如果找不到该值,则返回-1
函数签名:
func LastIndexOf[T comparable](slice []T, item T) int
示例:运行
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
对slice中的每个元素执行map函数以创建一个新切片。
函数签名:
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U
示例:运行
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]
}
MapConcurrent
对slice并发执行map操作。
函数签名:
func MapConcurrent[T any, U any](slice []T, iteratee func(index int, item T) U, numThreads int) []U
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5, 6}
result := slice.MapConcurrent(nums, func(_, n int) int {
return n * n
}, 4)
fmt.Println(result)
// Output:
// [1 4 9 16 25 36]
}
FilterMap
返回一个将filter和map操作应用于给定切片的切片。 iteratee回调函数应该返回两个值:1,结果值。2,结果值是否应该被包含在返回的切片中。
函数签名:
func FilterMap[T any, U any](slice []T, iteratee func(index int, item T) (U, bool)) []U
示例:运行
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
将切片转换为其它类型切片。
函数签名:
func FlatMap[T any, U any](slice []T, iteratee func(index int, item T) []U) []U
示例:运行
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
合并多个切片(不会消除重复元素).
⚠️ 本函数已弃用,使用
Concat
代替。
函数签名:
func Merge[T any](slices ...[]T) []T
示例:运行
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
反转切片中的元素顺序
函数签名:
func Reverse[T any](slice []T)
示例:运行
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
将切片中的元素依次运行iteratee函数,返回运行结果。
⚠️ 本函数已弃用,使用
ReduceBy
代替。
函数签名:
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T
示例:运行
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
}
ReduceConcurrent
对切片元素执行并发reduce操作。
函数签名:
func ReduceConcurrent[T any](slice []T, initial T, reducer func(index int, item T, agg T) T, numThreads int) T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
result := slice.ReduceConcurrent(nums, 0, func(_ int, item, agg int) int {
return agg + item
}, 1)
fmt.Println(result)
// Output:
// 55
}
ReduceBy
对切片元素执行reduce操作。
函数签名:
func ReduceBy[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U
示例:运行
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
类似ReduceBy操作,迭代切片元素顺序从右至左。
函数签名:
func ReduceRight[T any, U any](slice []T, initial U, reducer func(index int, item T, agg U) U) U
示例:运行
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
返回切片的副本,其中前n个不重叠的old替换为new
函数签名:
func Replace[T comparable](slice []T, old T, new T, n int) []T
示例:运行
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
返回切片的副本,将其中old全部替换为new
函数签名:
func ReplaceAll[T comparable](slice []T, old T, new T) []T
示例:运行
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
创建一个切片,包含n个传入的item
函数签名:
func Repeat[T any](item T, n int) []T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
result := slice.Repeat("a", 3)
fmt.Println(result)
// Output:
// [a a a]
}
Shuffle
随机打乱切片中的元素顺序
函数签名:
func Shuffle[T any](slice []T) []T
示例:运行
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
检查切片元素是否按升序排列。
函数签名:
func IsAscending[T constraints.Ordered](slice []T) bool
示例:运行
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
检查切片元素是否按降序排列。
函数签名:
func IsDescending[T constraints.Ordered](slice []T) bool
示例:运行
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
检查切片元素是否是有序的(升序或降序)。
函数签名:
func IsSorted[T constraints.Ordered](slice []T) bool
示例:运行
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
通过iteratee函数,检查切片元素是否是有序的。
函数签名:
func IsSortedByKey[T any, K constraints.Ordered](slice []T, iteratee func(item T) K) bool
示例:运行
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
对任何有序类型(数字或字符串)的切片进行排序,使用快速排序算法。 默认排序顺序为升序 (asc),如果需要降序,请将参数 `sortOrder` 设置为 `desc`。 Ordered类型:数字(所有整数浮点数)或字符串。
函数签名:
func Sort[T constraints.Ordered](slice []T, sortOrder ...string)
示例:运行
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
按照less函数确定的升序规则对切片进行排序。排序不保证稳定性
函数签名:
func SortBy[T any](slice []T, less func(a, b T) bool)
示例:运行
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
按字段对结构体切片进行排序。slice元素应为struct,排序字段field类型应为int、uint、string或bool。 默认排序类型是升序(asc),如果是降序,设置 sortType 为 desc
函数签名:
func SortByField(slice any, field string, sortType ...string) error
示例:运行
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
如果列表中的任何值通过谓词函数,则返回true
函数签名:
func Some[T any](slice []T, predicate func(index int, item T) bool) bool
示例:运行
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
将接口切片转换为字符串切片
⚠️ 本函数已弃用,使用go1.18+泛型代替。
函数签名:
func StringSlice(slice any) []string
示例:运行
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
返回一个切片,其中的元素存在于参数切片中,但不同时存储在于参数切片中(交集取反)
函数签名:
func SymmetricDifference[T comparable](slices ...[]T) []T
示例:运行
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
将可变参数转为切片
函数签名:
func ToSlice[T any](items ...T) []T
示例:运行
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
将可变参数转为指针切片
函数签名:
func ToSlicePointer[T any](items ...T) []*T
示例:运行
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
删除切片中的重复元素
函数签名:
func Unique[T comparable](slice []T) []T
示例:运行
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
根据迭代函数返回的值,从输入切片中移除重复元素。此函数保持元素的顺序。
函数签名:
func UniqueBy[T any, U comparable](slice []T, iteratee func(item T) U) []T
示例:运行
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 3]
}
UniqueByComparator
使用提供的比较器函数从输入切片中移除重复元素。此函数保持元素的顺序。
函数签名:
func UniqueByComparator[T comparable](slice []T, comparator func(item T, other T) bool) []T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
uniqueNums := slice.UniqueByComparator([]int{1, 2, 3, 1, 2, 4, 5, 6, 4}, func(item int, other int) bool {
return item == other
})
caseInsensitiveStrings := slice.UniqueByComparator([]string{"apple", "banana", "Apple", "cherry", "Banana", "date"}, func(item string, other string) bool {
return strings.ToLower(item) == strings.ToLower(other)
})
fmt.Println(uniqueNums)
fmt.Println(caseInsensitiveStrings)
// Output:
// [1 2 3 4 5 6]
// [apple banana cherry date]
}
UniqueByConcurrent
并发的从输入切片中移除重复元素,结果保持元素的顺序。
函数签名:
func UniqueByConcurrent[T comparable](slice []T, comparator func(item T, other T) bool, numThreads int) []T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
nums := []int{1, 2, 3, 1, 2, 4, 5, 6, 4, 7}
comparator := func(item int, other int) bool { return item == other }
result := slice.UniqueByConcurrent(nums, comparator, 4)
fmt.Println(result)
// Output:
// [1 2 3 4 5 6 7]
}
UniqueByField
根据struct字段对struct切片去重复。
函数签名:
func UniqueByField[T any](slice []T, field string) ([]T, error)
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
users := []User{
{ID: 1, Name: "a"},
{ID: 2, Name: "b"},
{ID: 1, Name: "c"},
}
result, err := slice.UniqueByField(users, "ID")
if err != nil {
}
fmt.Println(result)
// Output:
// [{1 a} {2 b}]
}
Union
合并多个切片
函数签名:
func Union[T comparable](slices ...[]T) []T
示例:运行
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
对切片的每个元素调用函数后,合并多个切片
函数签名:
func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T
示例:运行
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
更新索引处的切片元素。 如果index < 0或 index <= len(slice),将返回错误
函数签名:
func UpdateAt[T any](slice []T, index int, value T) []T
示例:运行
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
创建一个不包括所有给定值的切片
函数签名:
func Without[T comparable](slice []T, items ...T) []T
示例:运行
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
将切片每个元素调用函数后转为map。
函数签名:
func KeyBy[T any, U comparable](slice []T, iteratee func(item T) U) map[U]T
示例:运行
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
用指定的分隔符链接切片元素。
函数签名:
func Join[T any](s []T, separator string) string
示例:运行
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
}
Partition
根据给定的predicate判断函数分组切片元素。
函数签名:
func Partition[T any](slice []T, predicates ...func(item T) bool) [][]T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
result1 := slice.Partition(nums)
result2 := slice.Partition(nums, func(n int) bool { return n%2 == 0 })
result3 := slice.Partition(nums, func(n int) bool { return n == 1 || n == 2 }, func(n int) bool { return n == 2 || n == 3 || n == 4 })
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
// Output:
// [[1 2 3 4 5]]
// [[2 4] [1 3 5]]
// [[1 2] [3 4] [5]]
}
Random
随机返回切片中元素以及下标, 当切片长度为0时返回下标-1
函数签名:
func Random[T any](slice []T) (val T, idx int)
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
val, idx := slice.Random(nums)
if idx >= 0 && idx < len(nums) && slice.Contain(nums, val) {
fmt.Println("okk")
}
// Output:
// okk
}
SetToDefaultIf
根据给定给定的predicate判定函数来修改切片中的元素。对于满足的元素,将其替换为指定的默认值,同时保持元素在切片中的位置不变。函数返回修改后的切片以及被修改的元素个数。
函数签名:
func SetToDefaultIf[T any](slice []T, predicate func(T) bool) ([]T, int)
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
strs := []string{"a", "b", "a", "c", "d", "a"}
modifiedStrs, count := slice.SetToDefaultIf(strs, func(s string) bool { return "a" == s })
fmt.Println(modifiedStrs)
fmt.Println(count)
// Output:
// [ b c d ]
// 3
}
Break
根据判断函数将切片分成两部分。它开始附加到与函数匹配的第一个元素之后的第二个切片。第一个匹配之后的所有元素都包含在第二个切片中,无论它们是否与函数匹配。
函数签名:
func Break[T any](values []T, predicate func(T) bool) ([]T, []T)
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
even := func(n int) bool { return n%2 == 0 }
resultEven, resultAfterFirstEven := slice.Break(nums, even)
fmt.Println(resultEven)
fmt.Println(resultAfterFirstEven)
// Output:
// [1]
// [2 3 4 5]
}
RightPadding
在切片的右部添加元素。
函数签名:
func RightPadding[T any](slice []T, paddingValue T, paddingLength int) []T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
padded := slice.RightPadding(nums, 0, 3)
fmt.Println(padded)
// Output:
// [1 2 3 4 5 0 0 0]
}
LeftPadding
在切片的左部添加元素。
函数签名:
func LeftPadding[T any](slice []T, paddingValue T, paddingLength int) []T
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
padded := slice.LeftPadding(nums, 0, 3)
fmt.Println(padded)
// Output:
// [0 0 0 1 2 3 4 5]
}
Frequency
计算切片中每个元素出现的频率。
函数签名:
func Frequency[T comparable](slice []T) map[T]int
示例:运行
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
strs := []string{"a", "b", "b", "c", "c", "c"}
result := slice.Frequency(strs)
fmt.Println(result)
// Output:
// map[a:1 b:2 c:3]
}