/go/src/github.com/samber/lo 切片转MAP
·
samber/lo 库提供了多个函数用于将切片(Slice)转换为 Map,比手写循环更简洁安全。以下是主要用法:
核心函数
1. Associate(键值自定义)
将切片转换为 map,同时定义 key 和 value 的生成逻辑:
go
复制
import "github.com/samber/lo"
users := []User{
{ID: 1, Name: "Alice", Age: 25},
{ID: 2, Name: "Bob", Age: 30},
}
// map[ID]Name
nameMap := lo.Associate(users, func(u User) (int, string) {
return u.ID, u.Name
})
// 结果: map[1:Alice 2:Bob]
2. KeyBy(按字段索引)
最常用,元素本身作为 value,key 由函数决定:
go
复制
// map[ID]User - 快速根据 ID 查找用户
userMap := lo.KeyBy(users, func(u User) int {
return u.ID
})
// 使用
if user, ok := userMap[1]; ok {
fmt.Println(user.Name)
}
3. GroupBy(分组聚合)
当 key 可能重复时,生成 map[K][]T:
go
复制
usersByAge := lo.GroupBy(users, func(u User) int {
return u.Age
})
// 结果: map[25:[{1 Alice 25}] 30:[{2 Bob 30}]]
对比与选择
表格
复制
| 函数 | 返回类型 | 适用场景 | 冲突处理 |
|---|---|---|---|
KeyBy |
map[K]T |
建立主键索引 | 后覆盖前 |
Associate |
map[K]V |
提取特定字段组合 | 后覆盖前 |
GroupBy |
map[K][]T |
一对多关系 | 收集到切片 |
实战示例
go
复制
package main
import (
"fmt"
"github.com/samber/lo"
)
type User struct {
ID int
Name string
Dept string
}
func main() {
users := []User{
{1, "Alice", "Tech"},
{2, "Bob", "Tech"},
{3, "Charlie", "HR"},
}
// 场景1: ID 快速查找
userMap := lo.KeyBy(users, func(u User) int { return u.ID })
// 场景2: 只取 Name 映射
idToName := lo.Associate(users,
func(u User) (int, string) { return u.ID, u.Name },
)
// 场景3: 按部门分组
deptGroups := lo.GroupBy(users, func(u User) string { return u.Dept })
fmt.Println(userMap[1].Name) // Alice
fmt.Println(idToName[2]) // Bob
fmt.Println(len(deptGroups["Tech"])) // 2
}
注意事项
-
重复 Key 处理:
-
KeyBy和Associate遇到重复 key 时,后面元素覆盖前面 -
如需保留所有,改用
GroupBy
-
-
性能:
-
内部已优化内存预分配(
make(map[...], len(collection))) -
比手写
for循环更简洁且无需担心容量问题
-
-
空切片安全:
-
传入空切片返回空 map(非 nil),可直接安全使用
-
安装:go get github.com/samber/lo
更多推荐



所有评论(0)