Contents

Go lo

Contents

Go lo

使用

go get github.com/samber/lo

使用

// 将切片中的重复元素去掉,只保留第一个出现的元素。
names := lo.Uniq([]string{"Samuel", "John", "Samuel"})
// []string{"Samuel", "John"}

// 生成map
// 将切片或数组转换为map,key是callback函数的返回值,value是对应的元素。 当key相同时,后面的元素会覆盖前面的元素。
type abc struct {
	A string
}
aa := []*abc{}
lo.KeyBy(aa, func(item *abc) string {
	return item.A
})



// Associate (alias: SliceToMap)
// 对切片遍历生成一个Map,key和value由callback函数生成。key是第一个返回值,value是第二个返回值。如果key相同,后面的元素会覆盖前面的元素。
in := []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}}
aMap := lo.Associate(in, func (f *foo) (string, int) {
    return f.baz, f.bar
})
// map[string][int]{ "apple":1, "banana":2 }

// Drop
// 去掉切片的前n个元素。
l := lo.Drop([]int{0, 1, 2, 3, 4, 5}, 2)
// []int{2, 3, 4, 5}


// DropRight
// 去掉切片的后n个元素。
l := lo.DropRight([]int{0, 1, 2, 3, 4, 5}, 2)
// []int{0, 1, 2, 3}



// DropWhile
// DropWhile 会一直删除元素,直到predicate返回false。
l := lo.DropWhile([]string{"a", "aa", "aaa", "aa", "aa"}, func(val string) bool {
    return len(val) <= 2
})
// []string{"aaa", "aa", "aa"}


// 计算切片中和value相等的元素的个数。
count := lo.Count([]int{1, 5, 1}, 1)
// 2

// 计算切片中满足predicate函数的元素的个数。
count := lo.CountBy([]int{1, 5, 1}, func(i int) bool {
    return i < 4
})
// 2

// CountValues
// 计算切片中每个元素的个数。其中key是元素,value是个数。
lo.CountValues([]int{})
// map[int]int{}
lo.CountValues([]int{1, 2})
// map[int]int{1: 1, 2: 1}
lo.CountValues([]int{1, 2, 2})
// map[int]int{1: 1, 2: 2}

// Subset
// 返回切片中从offset开始的length个元素。但是不会因为越界而panic。
in := []int{0, 1, 2, 3, 4}
sub := lo.Subset(in, 2, 3)
// []int{2, 3, 4}


// Slice
// 返回一个切片的副本,从start到end,但是不包括end。不会因为越界而panic。
in := []int{0, 1, 2, 3, 4}
slice := lo.Slice(in, 0, 5)
// []int{0, 1, 2, 3, 4}
slice := lo.Slice(in, 2, 3)
// []int{2}

// Compact
// 去掉所有零值
in := []string{"", "foo", "", "bar", ""}

slice := lo.Compact[string](in)
// []string{"foo", "bar"}




// 切片类型转换
lo.Map([]int64{1, 2, 3, 4}, func(x int64, index int) string {
    return strconv.FormatInt(x, 10)
})
// []string{"1", "2", "3", "4"}




// 对某一个函数调用n次,返回结果的切片。i为索引, 从0开始。
lo.Times(3, func(i int) string {
    return strconv.FormatInt(int64(i), 10)
})
// []string{"0", "1", "2"}


// chunk 分片
lo.Chunk([]int{0, 1, 2, 3, 4, 5}, 2)

// 展开二维切片
flat := lo.Flatten([][]int{{0, 1}, {2, 3, 4, 5}})
// []int{0, 1, 2, 3, 4, 5}


// 洗牌
// 返回一个打乱顺序的切片, 使用Fisher-Yates shuffle Fisher-Yates shuffle
randomOrder := lo.Shuffle([]int{0, 1, 2, 3, 4, 5})
// []int{1, 4, 0, 3, 5, 2}


// 反转
// 反转切片,第一个元素变成最后一个,第二个元素变成倒数第二个,以此类推。
reverseOrder := lo.Reverse([]int{0, 1, 2, 3, 4, 5})

// Repeat
// 生成一个切片,包含N个相同的元素。
slice := lo.Repeat(2, foo{"a"})
// []foo{foo{"a"}, foo{"a"}}




// Splice 指定索引插入切片
result := lo.Splice([]string{"a", "b"}, 1, "1", "2")
// []string{"a", "1", "2", "b"}

// 获取map的key
keys := lo.Keys(map[string]int{"foo": 1, "bar": 2})
// []string{"foo", "bar"}

// 判断key是否存在
exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "foo")
// true



// 获取map的值
values := lo.Values(map[string]int{"foo": 1, "bar": 2})
// []int{1, 2}

// 获取map的值并去重
values := lo.UniqValues(map[string]int{"foo": 1, "bar": 2})
// []int{1, 2}

// 求和
list := []int{1, 2, 3, 4, 5}
sum := lo.Sum(list)
// 15



// 计算平均值
mean := lo.Mean([]int{2, 3, 4, 5})
// 3


// 随机字符串
str := lo.RandomString(5, lo.LettersCharset)
// example: "eIGbt"

// 获取子串
sub := lo.Substring("hello", 2, 3)
// "llo"

// 驼峰
str := lo.PascalCase("hello_world")
// HelloWorld

str := lo.CamelCase("hello_world")
// helloWorld

str := lo.KebabCase("helloWorld")
// hello-world

// 蛇型
str := lo.SnakeCase("HelloWorld")
// hello_world

// 依据大写拆分单词
str := lo.Words("helloWorld")
// []string{"hello", "world"}

// 首字母大写
str := lo.Capitalize("heLLO")
// Hello


// 获取job执行的时间
duration := lo.Duration(func() {
    // very long job
})
// 3s

// 判断元素是否包含
ok := lo.Every([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
// true
ok := lo.Every([]int{0, 1, 2, 3, 4, 5}, []int{0, 6})
// false

// 判断切片不同,left是第二个切片缺少的,right是第一个切片缺少的
left, right := lo.Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 6})
// []int{1, 3, 4, 5}, []int{6}



// 删除元素
subset := lo.Without([]int{0, 2, 10}, 2)
// []int{0, 10}
subset := lo.Without([]int{0, 2, 10}, 0, 1, 2, 3, 4, 5)
// []int{10}


// 获取元素下标
found := lo.IndexOf([]int{0, 1, 2, 1, 2, 3}, 2)
// 2
notFound := lo.IndexOf([]int{0, 1, 2, 1, 2, 3}, 6)
// -1


// 查找元素
str, ok := lo.Find([]string{"a", "b", "c", "d"}, func(i string) bool {
    return i == "b"
})
// "b", true


// 获取较小的时间
earliest := lo.Earliest(time.Now(), time.Time{})
// 0001-01-01 00:00:00 +0000 UTC

// 获取较晚的时间
latest := lo.Latest([]time.Time{time.Now(), time.Time{}})
// 2023-04-01 01:02:03 +0000 UTC


// 获取第一个元素,没有则给定默认值
first := lo.FirstOr([]int{1, 2, 3}, 245)
// 1

first := lo.FirstOr([]int{}, 31)
// 31

// 获取最后一个元素,没有则给定默认值
last := lo.LastOr([]int{1, 2, 3}, 245)
// 3


// swich 语法
result := lo.Switch(1).
    Case(1, "1").
    Case(2, "2").
    Default("3")
// "1"

result := lo.Switch(1).
    CaseF(1, func() string {
        return "1"
    }).
    CaseF(2, func() string {
        return "2"
    }).
    DefaultF(func() string {
        return "3"
    })
// "1"


// 判断是否为空
var x int
lo.IsNil(x)
// false

var k struct{}
lo.IsNil(k)
// false

var i *int
lo.IsNil(i)
// true

// 获取指针数据
ptr := lo.ToPtr("hello world")
// *string{"hello world"}

// 返回一个空指针数据
ptr := lo.Nil[float64]()
// nil


// 获取指针的值
str := "hello world"
value := lo.FromPtr(&str)
// "hello world"

value := lo.FromPtr(nil)
// ""

// 获取指针的值,设置默认值
str := "hello world"
value := lo.FromPtrOr(&str, "empty")
// "hello world"

value := lo.FromPtrOr(nil, "empty")
// "empty"