diff --git a/mapUtil/README.md b/mapUtil/README.md index a8c1530..b775c39 100644 --- a/mapUtil/README.md +++ b/mapUtil/README.md @@ -22,4 +22,10 @@ func MapKeyExists((m map[T]T2, key T)) bool // MapValueExists 判断map中的value是否存在 func MapValueExists(m map[T2]T, value T) bool + +// ExtractKeys 提取Map的所有键 +func ExtractKeys[K comparable, V any](m map[K]V) []K + +// ExtractValues 提取Map的所有值 +func ExtractValues[K comparable, V any](m map[K]V) []V ``` \ No newline at end of file diff --git a/mapUtil/extract_keys.go b/mapUtil/extract_keys.go new file mode 100644 index 0000000..692b7a4 --- /dev/null +++ b/mapUtil/extract_keys.go @@ -0,0 +1,10 @@ +package mapUtil + +// ExtractKeys 提取Map的所有键 +func ExtractKeys[K comparable, V any](m map[K]V) []K { + keys := make([]K, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + return keys +} diff --git a/mapUtil/extract_keys_example_test.go b/mapUtil/extract_keys_example_test.go new file mode 100644 index 0000000..e5c4c00 --- /dev/null +++ b/mapUtil/extract_keys_example_test.go @@ -0,0 +1,17 @@ +package mapUtil + +import ( + "fmt" + "sort" +) + +func ExampleExtractKeys() { + m := map[string]int{"apple": 5, "banana": 3, "orange": 7} + keys := ExtractKeys(m) + + // 对结果排序以确保输出一致(map 迭代顺序随机) + sort.Strings(keys) + fmt.Println("Keys:", keys) + + // Output: Keys: [apple banana orange] +} diff --git a/mapUtil/extract_keys_test.go b/mapUtil/extract_keys_test.go new file mode 100644 index 0000000..7263534 --- /dev/null +++ b/mapUtil/extract_keys_test.go @@ -0,0 +1,121 @@ +package mapUtil + +import ( + "sort" + "testing" +) + +func TestExtractKeys(t *testing.T) { + tests := []struct { + name string + input map[string]int + expected []string + }{ + { + name: "Normal map", + input: map[string]int{"a": 1, "b": 2, "c": 3}, + expected: []string{"a", "b", "c"}, + }, + { + name: "Empty map", + input: map[string]int{}, + expected: []string{}, + }, + { + name: "Single element", + input: map[string]int{"x": 10}, + expected: []string{"x"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ExtractKeys(tt.input) + + // 对结果排序,因为 map 迭代顺序是随机的 + sort.Strings(result) + sort.Strings(tt.expected) + + if len(result) != len(tt.expected) { + t.Errorf("Expected %d keys, got %d", len(tt.expected), len(result)) + return + } + + for i := range result { + if result[i] != tt.expected[i] { + t.Errorf("At index %d: expected %q, got %q", i, tt.expected[i], result[i]) + } + } + }) + } +} + +func TestExtractKeys2(t *testing.T) { + tests := []struct { + name string + input map[int]string + expected []int + }{ + { + name: "int和string类型的map", + input: map[int]string{1: "one", 2: "two"}, + expected: []int{1, 2}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ExtractKeys(tt.input) + + // 对结果排序,因为 map 迭代顺序是随机的 + sort.Ints(result) + sort.Ints(tt.expected) + + if len(result) != len(tt.expected) { + t.Errorf("Expected %d keys, got %d", len(tt.expected), len(result)) + return + } + + for i := range result { + if result[i] != tt.expected[i] { + t.Errorf("At index %d: expected %q, got %q", i, tt.expected[i], result[i]) + } + } + }) + } +} + +func TestExtractKeys3(t *testing.T) { + tests := []struct { + name string + input map[float64]bool + expected []float64 + }{ + { + name: "float64和bool类型的map", + input: map[float64]bool{3.14: true, 2.71: false}, + expected: []float64{2.71, 3.14}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ExtractKeys(tt.input) + + // 对结果排序,因为 map 迭代顺序是随机的 + sort.Float64s(result) + sort.Float64s(tt.expected) + + if len(result) != len(tt.expected) { + t.Errorf("Expected %d keys, got %d", len(tt.expected), len(result)) + return + } + + for i := range result { + if result[i] != tt.expected[i] { + t.Errorf("At index %d: expected %f, got %f", i, tt.expected[i], result[i]) + } + } + }) + } +} diff --git a/mapUtil/extract_values.go b/mapUtil/extract_values.go new file mode 100644 index 0000000..da3d5d6 --- /dev/null +++ b/mapUtil/extract_values.go @@ -0,0 +1,10 @@ +package mapUtil + +// ExtractValues 提取Map的所有值 +func ExtractValues[K comparable, V any](m map[K]V) []V { + values := make([]V, 0, len(m)) + for _, v := range m { + values = append(values, v) + } + return values +} diff --git a/mapUtil/extract_values_example_test.go b/mapUtil/extract_values_example_test.go new file mode 100644 index 0000000..85dfc1e --- /dev/null +++ b/mapUtil/extract_values_example_test.go @@ -0,0 +1,17 @@ +package mapUtil + +import ( + "fmt" + "sort" +) + +func ExampleExtractValues() { + m := map[string]int{"apple": 5, "banana": 3, "orange": 7} + values := ExtractValues(m) + + // 对结果排序以确保输出一致(map 迭代顺序随机) + sort.Ints(values) + fmt.Println("Values:", values) + + // Output: Values: [3 5 7] +} diff --git a/mapUtil/extract_values_test.go b/mapUtil/extract_values_test.go new file mode 100644 index 0000000..447374c --- /dev/null +++ b/mapUtil/extract_values_test.go @@ -0,0 +1,123 @@ +package mapUtil + +import ( + "sort" + "testing" +) + +func TestExtractValues(t *testing.T) { + tests := []struct { + name string + input map[string]int + expected []int + }{ + { + name: "Normal map", + input: map[string]int{"a": 1, "b": 2, "c": 3}, + expected: []int{1, 2, 3}, + }, + { + name: "Empty map", + input: map[string]int{}, + expected: []int{}, + }, + { + name: "Single element", + input: map[string]int{"x": 10}, + expected: []int{10}, + }, + { + name: "Duplicate values", + input: map[string]int{"a": 5, "b": 5, "c": 5}, + expected: []int{5, 5, 5}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ExtractValues(tt.input) + + // 对结果排序,因为 map 迭代顺序是随机的 + sort.Ints(result) + sort.Ints(tt.expected) + + if len(result) != len(tt.expected) { + t.Errorf("Expected %d values, got %d", len(tt.expected), len(result)) + return + } + + for i := range result { + if result[i] != tt.expected[i] { + t.Errorf("At index %d: expected %d, got %d", i, tt.expected[i], result[i]) + } + } + }) + } +} + +func TestExtractValues2(t *testing.T) { + tests := []struct { + name string + input map[int]string + expected []string + }{ + { + name: "int和string类型的map", + input: map[int]string{1: "one", 2: "two"}, + expected: []string{"one", "two"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ExtractValues(tt.input) + + // 对结果排序,因为 map 迭代顺序是随机的 + sort.Strings(result) + sort.Strings(tt.expected) + + if len(result) != len(tt.expected) { + t.Errorf("Expected %d values, got %d", len(tt.expected), len(result)) + return + } + + for i := range result { + if result[i] != tt.expected[i] { + t.Errorf("At index %d: expected %s, got %s", i, tt.expected[i], result[i]) + } + } + }) + } +} + +func TestExtractValues3(t *testing.T) { + type Point struct{ X, Y int } + + tests := []struct { + name string + input map[string]Point + expected []Point + }{ + { + name: "结构体类型的map", + input: map[string]Point{ + "origin": {X: 0, Y: 0}, + "top": {X: 0, Y: 10}, + }, + expected: []Point{ + {X: 0, Y: 0}, + {X: 0, Y: 10}, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := ExtractValues(tt.input) + + if len(result) != len(tt.expected) { + t.Errorf("Expected %v, got %v", tt.expected, result) + } + }) + } +}