mirror of
https://github.com/jefferyjob/go-easy-utils.git
synced 2025-09-26 19:11:12 +08:00
支持 ExtractKeys 和 ExtractValues 方法 (#92)
This commit is contained in:
@@ -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
|
||||
```
|
10
mapUtil/extract_keys.go
Normal file
10
mapUtil/extract_keys.go
Normal file
@@ -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
|
||||
}
|
17
mapUtil/extract_keys_example_test.go
Normal file
17
mapUtil/extract_keys_example_test.go
Normal file
@@ -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]
|
||||
}
|
121
mapUtil/extract_keys_test.go
Normal file
121
mapUtil/extract_keys_test.go
Normal file
@@ -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])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
10
mapUtil/extract_values.go
Normal file
10
mapUtil/extract_values.go
Normal file
@@ -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
|
||||
}
|
17
mapUtil/extract_values_example_test.go
Normal file
17
mapUtil/extract_values_example_test.go
Normal file
@@ -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]
|
||||
}
|
123
mapUtil/extract_values_test.go
Normal file
123
mapUtil/extract_values_test.go
Normal file
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user