mirror of
https://github.com/jefferyjob/go-easy-utils.git
synced 2025-09-27 11:22:29 +08:00
@@ -37,4 +37,10 @@ func SumSlice(slice []T) T
|
|||||||
|
|
||||||
// Unique 移除slice中重复的值
|
// Unique 移除slice中重复的值
|
||||||
func UniqueSlice(slice []T) []T
|
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