Skip to content

Commit

Permalink
增加两个func MapWithE2KFunc, MapWithE2KVFunc
Browse files Browse the repository at this point in the history
  • Loading branch information
dxyinme committed Mar 31, 2024
1 parent 0662fcc commit d98fcb5
Show file tree
Hide file tree
Showing 2 changed files with 257 additions and 0 deletions.
54 changes: 54 additions & 0 deletions slice/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,60 @@ func Map[Src any, Dst any](src []Src, m func(idx int, src Src) Dst) []Dst {
return dst
}

// 将[]Ele映射到map[Key]Ele
// 从Ele中提取Key的函数E2KFunc由使用者提供
//
// 注意:
// 如果出现 i < j
// 设:
//
// key_i := E2KFunc(elements[i])
// key_j := E2KFunc(elements[j])
//
// 满足key_i == key_j 的情况,则在返回结果的resultMap中
// resultMap[key_i] = val_j
//
// 即使传入的字符串为nil,也保证返回的map是一个空map而不是nil
func MapWithE2KFunc[Ele any, Key comparable](
elements []Ele,
E2KFunc func(element Ele) Key,
) map[Key]Ele {
return MapWithE2KVFunc(
elements,
func(element Ele) (Key, Ele) {
return E2KFunc(element), element
})
}

// 将[]Ele映射到map[Key]Val
// 从Ele中提取Key和Val的函数E2KVFunc由使用者提供
//
// 注意:
// 如果出现 i < j
// 设:
//
// key_i, val_i := E2KVFunc(elements[i])
// key_j, val_j := E2KVFunc(elements[j])
//
// 满足key_i == key_j 的情况,则在返回结果的resultMap中
// resultMap[key_i] = val_j
//
// 即使传入的字符串为nil,也保证返回的map是一个空map而不是nil
func MapWithE2KVFunc[Ele any, Key comparable, Val any](
elements []Ele,
E2KVFunc func(element Ele) (Key, Val),
) (resultMap map[Key]Val) {
resultMap = make(map[Key]Val)
if elements == nil {
return
}
for _, element := range elements {
k, v := E2KVFunc(element)
resultMap[k] = v
}
return
}

// 构造map
func toMap[T comparable](src []T) map[T]struct{} {
var dataMap = make(map[T]struct{}, len(src))
Expand Down
203 changes: 203 additions & 0 deletions slice/map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,206 @@ func ExampleFilterMap() {
fmt.Println(dst)
// Output: [1 3]
}

func TestMapWithE2KVFunc(t *testing.T) {
t.Run("integer-string to map[int]int", func(t *testing.T) {
elements := []string{"1", "2", "3", "4", "5"}
resMap := MapWithE2KVFunc(elements, func(str string) (int, int) {
num, _ := strconv.Atoi(str)
return num, num
})
epectedMap := map[int]int{
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
}
assert.Equal(t, epectedMap, resMap)
})
t.Run("struct<string, string, int> to map[string]struct<string, string, int>", func(t *testing.T) {
type eleType struct {
A string
B string
C int
}
elements := []eleType{
{
A: "a",
B: "b",
C: 1,
},
{
A: "c",
B: "d",
C: 2,
},
}
resMap := MapWithE2KVFunc(elements, func(ele eleType) (string, eleType) {
return ele.A, ele
})
epectedMap := map[string]eleType{
"a": {
A: "a",
B: "b",
C: 1,
},
"c": {
A: "c",
B: "d",
C: 2,
},
}
assert.Equal(t, epectedMap, resMap)
})

t.Run("struct<string, string, int> to map[string]struct<string, string, int>, 重复的key", func(t *testing.T) {
type eleType struct {
A string
B string
C int
}
elements := []eleType{
{
A: "a",
B: "b",
C: 1,
},
{
A: "c",
B: "d",
C: 2,
},
{
A: "a",
B: "d",
C: 3,
},
}
resMap := MapWithE2KVFunc(elements, func(ele eleType) (string, eleType) {
return ele.A, ele
})
epectedMap := map[string]eleType{
"a": {
A: "a",
B: "d",
C: 3,
},
"c": {
A: "c",
B: "d",
C: 2,
},
}
assert.Equal(t, epectedMap, resMap)
})

t.Run("传入nil slice,返回空map", func(t *testing.T) {
var elements []string = nil
resMap := MapWithE2KVFunc(elements, func(str string) (int, int) {
num, _ := strconv.Atoi(str)
return num, num
})
epectedMap := make(map[int]int)
assert.Equal(t, epectedMap, resMap)
})
}

func TestMapWithE2KFunc(t *testing.T) {
t.Run("integer-string to map[int]string", func(t *testing.T) {
elements := []string{"1", "2", "3", "4", "5"}
resMap := MapWithE2KFunc(elements, func(str string) int {
num, _ := strconv.Atoi(str)
return num
})
epectedMap := map[int]string{
1: "1",
2: "2",
3: "3",
4: "4",
5: "5",
}
assert.Equal(t, epectedMap, resMap)
})
t.Run("struct<string, string, int> to map[string]struct<string, string, int>", func(t *testing.T) {
type eleType struct {
A string
B string
C int
}
elements := []eleType{
{
A: "a",
B: "b",
C: 1,
},
{
A: "c",
B: "d",
C: 2,
},
}
resMap := MapWithE2KFunc(elements, func(ele eleType) string {
return ele.A
})
epectedMap := map[string]eleType{
"a": {
A: "a",
B: "b",
C: 1,
},
"c": {
A: "c",
B: "d",
C: 2,
},
}
assert.Equal(t, epectedMap, resMap)
})

t.Run("struct<string, string, int> to map[string]struct<string, string, int>, 重复的key", func(t *testing.T) {
type eleType struct {
A string
B string
C int
}
elements := []eleType{
{
A: "a",
B: "b",
C: 1,
},
{
A: "c",
B: "d",
C: 2,
},
}
resMap := MapWithE2KFunc(elements, func(ele eleType) string {
return ele.A
})
epectedMap := map[string]eleType{
"a": {
A: "a",
B: "b",
C: 1,
},
"c": {
A: "c",
B: "d",
C: 2,
},
}
assert.Equal(t, epectedMap, resMap)
})

t.Run("传入nil slice,返回空map", func(t *testing.T) {
var elements []string = nil
resMap := MapWithE2KFunc(elements, func(str string) int {
num, _ := strconv.Atoi(str)
return num
})
epectedMap := make(map[int]string)
assert.Equal(t, epectedMap, resMap)
})
}

0 comments on commit d98fcb5

Please sign in to comment.