# Slice
slice 包包含操作切片的方法集合。
# 源码:
# 用法:
import (
"github.com/duke-git/lancet/v2/slice"
)
# 文档
# AppendIfAbsent
当前切片中不包含值时,将该值追加到切片中
函数签名:
func AppendIfAbsent[T comparable](slice []T, value T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
strs := []string{"a", "b"}
res1 := slice.AppendIfAbsent(strs, "a")
fmt.Println(res1) //[]string{"a", "b"}
res2 := slice.AppendIfAbsent(strs, "cannot")
fmt.Println(res2"}
}
# Contain
判断slice是否包含value
函数签名:
func Contain[T comparable](slice []T, value T) bool
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res := slice.Contain([]string{"a", "b", "c"}, "a")
fmt.Println(res) //true
}
# ContainSubSlice
判断slice是否包含subslice
函数签名:
func ContainSubSlice[T comparable](slice, subslice []T) bool
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "b"})
fmt.Println(res) //true
}
# 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"}
res := slice.Chunk(InterfaceSlice(arr), 3)
fmt.Println(res) //[][]any{{"a", "b", "c"}, {"d", "e"}}
}
# Compact
去除slice中的假值(false values are false, nil, 0, "")
函数签名:
func Compact[T any](slice []T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res := slice.Compact([]int{0, 1, 2, 3})
fmt.Println(res) //[]int{1, 2, 3}
}
# Concat
连接values到slice中,values类型可以是切片或多个值
函数签名:
func Concat[T any](slice []T, values ...[]T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res1 := slice.Concat([]int{1, 2, 3}, 4, 5)
fmt.Println(res1) //[]int{1, 2, 3, 4, 5}
res2 := slice.Concat([]int{1, 2, 3}, []int{4, 5})
fmt.Println(res2) //[]int{1, 2, 3, 4, 5}
}
# Count
遍历切片,对每个元素执行函数function. 返回符合函数返回值为true的元素的个数
函数签名:
func Count[T any](slice []T, predicate func(index int, t T) bool) int
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4, 5, 6}
evenFunc := func(i, num int) bool {
return (num % 2) == 0
}
res := slice.Count(nums, evenFunc)
fmt.Println(res) //3
}
# 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}
res := slice.Difference(s1, s2)
fmt.Println(res) //[]int{1, 2, 3}
}
# DifferenceBy
在slice和comparedSlice中的每个元素调用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{4, 5, 6}
addOne := func(i int, v int) int {
return v + 1
}
res := slice.DifferenceBy(s1, s2, addOne)
fmt.Println(res) //[]int{1, 2}
}
# DifferenceWith
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
}
res := slice.DifferenceWith(s1, s2, isDouble)
fmt.Println(res) //[]int{1, 5}
}
# DeleteAt
删除切片中从开始索引到结束索引-1的元素
函数签名:
func DeleteAt[T any](slice []T, start int, end ...int)
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res1 := slice.DeleteAt([]string{"a", "b", "c", "d", "e"}, 3)
fmt.Println(res1) //[]string{"a", "b", "c", "e"}
res2 := slice.DeleteAt([]string{"a", "b", "c", "d", "e"}, 0, 2)
fmt.Println(res2) //[]string{"c", "d", "e"}
}
# Drop
创建一个切片,当 n > 0 时从开头删除 n 个元素,或者当 n < 0 时从结尾删除 n 个元素
函数签名:
func Drop[T any](slice []T, n int) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res1 := slice.Drop([]int{}, 0)
fmt.Println(res1) //[]int{}
res2 := slice.Drop([]int{1, 2, 3, 4, 5}, 1)
fmt.Println(res2) //[]int{2, 3, 4, 5}
res3 := slice.Drop([]int{1, 2, 3, 4, 5}, -1)
fmt.Println(res3) //[]int{1, 2, 3, 4}
}
# 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
}
res := slice.Every(nums, isEven)
fmt.Println(res) //false
}
# Equal
检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同
函数签名:
func Equal[T comparable](slice1, slice2 []T) bool
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
res1 := slice.Equal(slice1, slice2)
res2 := slice.Equal(slice1, slice3)
fmt.Println(res1) //true
fmt.Println(res2) //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() {
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
res := slice.EqualWith(slice1, slice2, isDouble)
fmt.Println(res) //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, 5}
isEven := func(i, num int) bool {
return num%2 == 0
}
res := slice.Filter(nums, isEven)
fmt.Println(res) //[]int{2, 4}
}
# Find
遍历切片的元素,返回第一个通过predicate函数真值测试的元素
函数签名:
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, 5}
isEven := func(i, num int) bool {
return num%2 == 0
}
res, ok := slice.Find(nums, even)
fmt.Println(res) //2
fmt.Println(ok) //true
}
# FindLast
从头到尾遍历slice的元素,返回最后一个通过predicate函数真值测试的元素。
函数签名:
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, 5}
isEven := func(i, num int) bool {
return num%2 == 0
}
res, ok := slice.FindLast(nums, even)
fmt.Println(res) //4
fmt.Println(ok) //true
}
# Flatten
将切片压平一层
函数签名:
func Flatten(slice any) any
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
res := slice.Flatten(arr)
fmt.Println(res) //{{"a", "b"}, {"c", "d"}}
}
# FlattenDeep
flattens slice recursive.
函数签名:
func FlattenDeep(slice any) any
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
res := slice.FlattenDeep(arr)
fmt.Println(res) //[]string{"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() {
numbers := []int{1, 2, 3, 4, 5}
var numbersAddTwo []int
slice.ForEach(numbers, func(index int, value int) {
numbersAddTwo = append(numbersAddTwo, value+2)
})
fmt.Println(numbersAddTwo) //[]int{3, 4, 5, 6, 7}
}
# 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, 6}
evenFunc := func(i, num int) bool {
return (num % 2) == 0
}
even, odd := slice.GroupBy(nums, evenFunc)
fmt.Println(even) //[]int{2, 4, 6}
fmt.Println(odd) //]int{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)
}
res := slice.GroupWith(nums, floor)
fmt.Println(res) //map[float64][]float64{ 4: {4.2}, 6: {6.1, 6.3},}
}
# IntSlice
将接口切片转换为int切片
函数签名:
func IntSlice(slice any) []int
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
var nums = []any{1, 2, 3}
res := slice.IntSlice(nums)
fmt.Println(res) //[]int{1, 2, 3}
}
# InterfaceSlice
将值转换为接口切片
函数签名:
func InterfaceSlice(slice any) []any
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
var nums = []int{}{1, 2, 3}
res := slice.InterfaceSlice(nums)
fmt.Println(res) //[]any{1, 2, 3}
}
# Intersection
多个切片的交集
函数签名:
func Intersection[T comparable](slices ...[]T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
s1 := []int{1, 2, 2, 3}
s2 := []int{1, 2, 3, 4}
res := slice.Intersection(s1, s2),
fmt.Println(res) //[]int{1, 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() {
s := []string{"a", "b", "c"}
res1, _ := slice.InsertAt(s, 0, "1")
fmt.Println(res1) //[]string{"1", "a", "b", "c"}
res2, _ := slice.InsertAt(s, 3, []string{"1", "2", "3"})
fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"}
}
# IndexOf
返回在切片中找到值的第一个匹配项的索引,如果找不到值,则返回-1
函数签名:
func IndexOf[T comparable](slice []T, value T) int
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.IndexOf(arr, "a")
fmt.Println(res1) //0
res2 := slice.IndexOf(arr, "d")
fmt.Println(res2) //-1
}
# LastIndexOf
返回在切片中找到最后一个值的索引,如果找不到该值,则返回-1
函数签名:
func LastIndexOf[T comparable](slice []T, value T) int
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.LastIndexOf(arr, "a")
fmt.Println(res1) //1
res2 := slice.LastIndexOf(arr, "d")
fmt.Println(res2) //-1
}
# Map
通过运行函数slice中的每个元素来创建一个新切片
函数签名:
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, 4}
multiplyTwo := func(i, num int) int {
return num * 2
}
res := slice.Map(nums, multiplyTwo)
fmt.Println(res) //[]int{2, 4, 6, 8}
}
# Reverse
反转切片中的元素顺序
函数签名:
func Reverse[T any](slice []T)
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 4}
slice.Reverse(nums)
fmt.Println(res) //[]int{4, 3, 2, 1}
}
# Reduce
将切片中的元素依次运行iteratee函数,返回运行结果
函数签名:
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, 4}
reduceFunc := func(i, v1, v2 int) int {
return v1 + v2
}
res := slice.Reduce(nums, reduceFunc, 0)
fmt.Println(res) //10
}
# 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}
res := slice.Shuffle(nums)
fmt.Println(res) //3,1,5,4,2
}
# SortByField
按字段对结构切片进行排序。slice元素应为struct,字段类型应为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 student struct {
name string
age int
}
students := []student{
{"a", 10},
{"b", 15},
{"c", 5},
{"d", 6},
}
err := slice.SortByField(students, "age", "desc")
if err != nil {
fmt.Println(err)
}
fmt.Println(students)
// []students{
// {"b", 15},
// {"a", 10},
// {"d", 6},
// {"c", 5},
// }
}
# 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
}
res := slice.Some(nums, isEven)
fmt.Println(res) //true
}
# StringSlice
将接口切片转换为字符串切片
函数签名:
func StringSlice(slice any) []string
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
var s = []any{"a", "b", "c"}
res := slice.StringSlice(s)
fmt.Println(res) //[]string{"a", "b", "c"}
}
# SymmetricDifference
返回一个切片,其中的元素存在于参数切片中,但不同时存储在于参数切片中(交集取反)
函数签名:
func SymmetricDifference[T comparable](slices ...[]T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
s1 := []int{1, 2, 3}
s2 := []int{1, 2, 4}
s3 := []int{1, 2, 3, 5}
fmt.Println(slice.SymmetricDifference(s1)) //[]int{1, 2, 3}
fmt.Println(slice.SymmetricDifference(s1, s2)) //[]int{3, 4}
fmt.Println(slice.SymmetricDifference(s1, s2, s3)) //[]int{3, 4, 5}
}
# ToSlice
将可变参数转为切片
函数签名:
func ToSlice[T any](value ...T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res := slice.ToSlice("a", "b")
fmt.Println(res) //{"a", "b"}
}
# ToSlicePointer
将可变参数转为指针切片
函数签名:
func ToSlicePointer[T any](value ...T) []*T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
str1 := "a"
str2 := "b"
res := slice.ToSlicePointer(str1, str2)
fmt.Println(res) // res -> []*string{&str1, &str2}
}
# Unique
删除切片中的重复元素
函数签名:
func Unique[T comparable](slice []T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res := slice.Unique([]int{1, 2, 2, 3})
fmt.Println(res) //[]int{1, 2, 3}
}
# UniqueBy
对切片的每个元素调用iteratee函数,然后删除重复元素
函数签名:
func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
res := slice.UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
fmt.Println(res) //[]int{1, 2, 3, 0}
}
# Union
从所有给定的切片按顺序创建一个唯一值切片,使用==进行相等比较
函数签名:
func Union[T comparable](slices ...[]T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
s1 := []int{1, 3, 4, 6}
s2 := []int{1, 2, 5, 6}
res := slice.Union(s1, s2)
fmt.Println(res) //[]int{1, 3, 4, 6, 2, 5}
}
# 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() {
s := []string{"a", "b", "c"}
res1, _ := slice.UpdateAt(s, 0, "1")
fmt.Println(res1) //[]string{"1", "b", "c"}
}
# Without
创建一个不包括所有给定值的切片
函数签名:
func Without[T comparable](slice []T, values ...T) []T
例子:
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res := slice.Without([]int{1, 2, 3, 4, 5}, 1, 2)
fmt.Println(res) //[]int{3, 4, 5}
}