Skip to content

Commit 40e0aa7

Browse files
authored
mapx 增加 merge 方法 (#276)
* mapx 增加 merge 方法 * 修复 lint,增加example
1 parent b832b6e commit 40e0aa7

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

mapx/map.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,31 @@ func ToMap[K comparable, V any](keys []K, values []V) (m map[K]V, err error) {
7272
}
7373
return
7474
}
75+
76+
// Merge 如果同一个键对应多个值,则会使用最后一个值
77+
func Merge[K comparable, V any](ms ...map[K]V) map[K]V {
78+
fc := func(val1, val2 V) V {
79+
return val2
80+
}
81+
return MergeFunc(fc, ms...)
82+
}
83+
84+
// MergeFunc 如果同一个键对应多个值,需要指定合并方式
85+
func MergeFunc[K comparable, V any](mergeFunc func(val1, val2 V) V, ms ...map[K]V) map[K]V {
86+
total := 0
87+
for _, m := range ms {
88+
total += len(m)
89+
}
90+
merged := make(map[K]V, total)
91+
92+
for _, m := range ms {
93+
for k, v := range m {
94+
if value, ok := merged[k]; ok {
95+
merged[k] = mergeFunc(value, v)
96+
} else {
97+
merged[k] = v
98+
}
99+
}
100+
}
101+
return merged
102+
}

mapx/map_example_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,36 @@ func (m MockKey) Equals(key any) bool {
6262
}
6363
return true
6464
}
65+
66+
func ExampleMerge() {
67+
m1 := map[int]int{1: 1, 2: 2, 3: 3}
68+
m2 := map[int]int{4: 4, 5: 5, 6: 6}
69+
got := mapx.Merge(m1, m2)
70+
fmt.Println(got)
71+
72+
m3 := map[int]int{1: 1, 2: 2, 3: 3}
73+
m4 := map[int]int{1: 5, 2: 6, 3: 7}
74+
got = mapx.Merge(m3, m4)
75+
fmt.Println(got)
76+
77+
var m map[int]int
78+
got = mapx.Merge(m)
79+
fmt.Println(got == nil) // 不会返回 nil map
80+
81+
// Output:
82+
// map[1:1 2:2 3:3 4:4 5:5 6:6]
83+
// map[1:5 2:6 3:7]
84+
// false
85+
}
86+
87+
func ExampleMergeFunc() {
88+
m1 := map[int]int{1: 1, 2: 2, 3: 3}
89+
m2 := map[int]int{1: 2, 2: 3, 3: 4}
90+
got := mapx.MergeFunc(func(val1, val2 int) int {
91+
return val1 + val2
92+
}, m1, m2)
93+
fmt.Println(got)
94+
95+
// Output:
96+
// map[1:3 2:5 3:7]
97+
}

mapx/map_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,54 @@ func TestToMap(t *testing.T) {
208208
assert.Equal(t, c.result, result)
209209
}
210210
}
211+
212+
func TestMerge(t *testing.T) {
213+
input1 := []map[int]int{
214+
{1: 1, 2: 2},
215+
{3: 3, 4: 4},
216+
}
217+
want1 := map[int]int{
218+
1: 1, 2: 2, 3: 3, 4: 4,
219+
}
220+
got := Merge(input1...)
221+
assert.Equal(t, want1, got)
222+
223+
input2 := []map[int]int{
224+
{1: 1, 2: 2},
225+
{3: 3, 4: 4},
226+
{2: 3, 4: 5},
227+
}
228+
want2 := map[int]int{
229+
1: 1, 2: 3, 3: 3, 4: 5,
230+
}
231+
got = Merge(input2...)
232+
assert.Equal(t, want2, got)
233+
}
234+
235+
func TestMergeFunc(t *testing.T) {
236+
input1 := []map[int]int{
237+
{1: 1, 2: 2},
238+
{1: 3, 2: 4},
239+
{3: 3, 4: 4},
240+
}
241+
want1 := map[int]int{
242+
1: 4, 2: 6, 3: 3, 4: 4,
243+
}
244+
got := MergeFunc(func(val1, val2 int) int {
245+
return val1 + val2
246+
}, input1...)
247+
assert.Equal(t, want1, got)
248+
249+
input2 := []map[int]int{
250+
{1: 1, 2: 2},
251+
{1: 3, 2: 4},
252+
{3: 3, 4: 4},
253+
}
254+
want2 := map[int]int{
255+
1: 3, 2: 8, 3: 3, 4: 4,
256+
}
257+
got = MergeFunc(func(val1, val2 int) int {
258+
return val1 * val2
259+
}, input2...)
260+
assert.Equal(t, want2, got)
261+
}

0 commit comments

Comments
 (0)