mirror of
https://github.com/jefferyjob/go-easy-utils.git
synced 2025-09-27 03:15:55 +08:00
@@ -37,4 +37,10 @@ func SumSlice(slice []T) T
|
||||
|
||||
// Unique 移除slice中重复的值
|
||||
func UniqueSlice(slice []T) []T
|
||||
|
||||
// SliceToMap 切片转字典
|
||||
func SliceToMap[T any, K comparable](items []T, keyFunc func(T) K) map[K]T
|
||||
|
||||
// ExtractKeys 字段提取
|
||||
func ExtractKeys[T any, K comparable](items []T, keyFunc func(T) K) []K
|
||||
```
|
10
sliceUtil/extract_keys.go
Normal file
10
sliceUtil/extract_keys.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package sliceUtil
|
||||
|
||||
// ExtractKeys 字段提取
|
||||
func ExtractKeys[T any, K comparable](items []T, keyFunc func(T) K) []K {
|
||||
var ids []K
|
||||
for _, v := range items {
|
||||
ids = append(ids, keyFunc(v))
|
||||
}
|
||||
return ids
|
||||
}
|
21
sliceUtil/extract_keys_example_test.go
Normal file
21
sliceUtil/extract_keys_example_test.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package sliceUtil
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ExampleExtractKeys() {
|
||||
type Person struct {
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
persons := []Person{
|
||||
{1, "Alice"},
|
||||
{2, "Bob"},
|
||||
{3, "Charlie"},
|
||||
}
|
||||
|
||||
keys := ExtractKeys(persons, func(p Person) int {
|
||||
return p.ID
|
||||
})
|
||||
fmt.Println(keys)
|
||||
// Output: [1 2 3]
|
||||
}
|
52
sliceUtil/extract_keys_test.go
Normal file
52
sliceUtil/extract_keys_test.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package sliceUtil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExtractKeysInline(t *testing.T) {
|
||||
// 使用匿名结构体定义测试数据
|
||||
persons := []struct {
|
||||
ID int
|
||||
Name string
|
||||
}{
|
||||
{1, "Alice"},
|
||||
{2, "Bob"},
|
||||
{3, "Charlie"},
|
||||
}
|
||||
|
||||
// 使用函数字面量定义 keyFunc 函数
|
||||
keys := ExtractKeys(persons, func(p struct {
|
||||
ID int
|
||||
Name string
|
||||
}) int {
|
||||
return p.ID
|
||||
})
|
||||
|
||||
expectedKeys := []int{1, 2, 3}
|
||||
if !reflect.DeepEqual(keys, expectedKeys) {
|
||||
t.Errorf("Expected keys %v, but got %v", expectedKeys, keys)
|
||||
}
|
||||
|
||||
// 另一个例子:使用不同的结构体和 keyFunc 函数
|
||||
animals := []struct {
|
||||
ID string
|
||||
Name string
|
||||
}{
|
||||
{"cat001", "Cat"},
|
||||
{"dog002", "Dog"},
|
||||
}
|
||||
|
||||
animalKeys := ExtractKeys(animals, func(a struct {
|
||||
ID string
|
||||
Name string
|
||||
}) string {
|
||||
return a.Name
|
||||
})
|
||||
|
||||
expectedAnimalKeys := []string{"Cat", "Dog"}
|
||||
if !reflect.DeepEqual(animalKeys, expectedAnimalKeys) {
|
||||
t.Errorf("Expected animal keys %v, but got %v", expectedAnimalKeys, animalKeys)
|
||||
}
|
||||
}
|
10
sliceUtil/slice_to_map.go
Normal file
10
sliceUtil/slice_to_map.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package sliceUtil
|
||||
|
||||
// SliceToMap 切片转字典
|
||||
func SliceToMap[T any, K comparable](items []T, keyFunc func(T) K) map[K]T {
|
||||
m := make(map[K]T)
|
||||
for _, item := range items {
|
||||
m[keyFunc(item)] = item
|
||||
}
|
||||
return m
|
||||
}
|
26
sliceUtil/slice_to_map_example_test.go
Normal file
26
sliceUtil/slice_to_map_example_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package sliceUtil
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ExampleSliceToMap 演示了 SliceToMap 函数的用法
|
||||
func ExampleSliceToMap() {
|
||||
type Person struct {
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
|
||||
people := []Person{
|
||||
{ID: 1, Name: "Alice"},
|
||||
{ID: 2, Name: "Bob"},
|
||||
{ID: 3, Name: "Charlie"},
|
||||
}
|
||||
|
||||
keyFunc := func(p Person) int {
|
||||
return p.ID
|
||||
}
|
||||
|
||||
peopleMap := SliceToMap(people, keyFunc)
|
||||
fmt.Println(peopleMap)
|
||||
// Output:
|
||||
// map[1:{1 Alice} 2:{2 Bob} 3:{3 Charlie}]
|
||||
}
|
62
sliceUtil/slice_to_map_test.go
Normal file
62
sliceUtil/slice_to_map_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package sliceUtil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSliceToMap(t *testing.T) {
|
||||
// Test case 1: Test with a slice of Person structs
|
||||
type Person struct {
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
|
||||
people := []Person{
|
||||
{ID: 1, Name: "Alice"},
|
||||
{ID: 2, Name: "Bob"},
|
||||
{ID: 3, Name: "Charlie"},
|
||||
}
|
||||
|
||||
keyFunc := func(p Person) int {
|
||||
return p.ID
|
||||
}
|
||||
|
||||
expected := map[int]Person{
|
||||
1: {ID: 1, Name: "Alice"},
|
||||
2: {ID: 2, Name: "Bob"},
|
||||
3: {ID: 3, Name: "Charlie"},
|
||||
}
|
||||
|
||||
result := SliceToMap(people, keyFunc)
|
||||
|
||||
if !reflect.DeepEqual(result, expected) {
|
||||
t.Errorf("Test case 1 failed. Expected %v, got %v", expected, result)
|
||||
}
|
||||
|
||||
// Test case 2: Test with an empty slice
|
||||
emptySlice := []Person{}
|
||||
expectedEmpty := map[int]Person{}
|
||||
|
||||
resultEmpty := SliceToMap(emptySlice, keyFunc)
|
||||
|
||||
if !reflect.DeepEqual(resultEmpty, expectedEmpty) {
|
||||
t.Errorf("Test case 2 failed. Expected %v, got %v", expectedEmpty, resultEmpty)
|
||||
}
|
||||
|
||||
// Test case 3: Test with a slice containing elements with the same key
|
||||
duplicatePeople := []Person{
|
||||
{ID: 1, Name: "Alice"},
|
||||
{ID: 1, Name: "Bob"},
|
||||
}
|
||||
|
||||
expectedDuplicate := map[int]Person{
|
||||
1: {ID: 1, Name: "Bob"}, // The last occurrence of the duplicate key will overwrite the previous one
|
||||
}
|
||||
|
||||
resultDuplicate := SliceToMap(duplicatePeople, keyFunc)
|
||||
|
||||
if !reflect.DeepEqual(resultDuplicate, expectedDuplicate) {
|
||||
t.Errorf("Test case 3 failed. Expected %v, got %v", expectedDuplicate, resultDuplicate)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user