前言
Go本身slice的方法是较少的,其他语言中的过滤和转换相关的经常使用的方法也没有,我们可以扩展一下方便使用。
切片slice
过滤
方法
通过一个函数参数来过滤所需的元素,只有满足条件元素才返回到结果集中:
func SliceFilter[T any](s []T, fn func(T) bool) []T {
result := make([]T, 0, len(s))
for _, v := range s {
if fn(v) {
result = append(result, v)
}
}
return result
}
判空也是常用的功能,获取所有非空集:
func SliceFilterNonNil[T any](s []*T) []*T {
return SliceFilter(s, func(t *T) bool {
return t != nil
})
}
调用
package test
import (
"fmt"
"strings"
"testing"
"xh-control-ws/utils"
)
// 普通的测试
func Test02(t *testing.T) {
var nameList []string
nameList = append(nameList, "张三", "李四", "王五")
result := utils.SliceFilter(nameList, func(item string) bool {
return strings.HasPrefix(item, "张")
})
fmt.Println(result) // 输出过滤后的结果
}
转换
方法
通过一个转换函数,可方便地把原切片转换为新的切片:
func SliceTrans[S, R any](s []S, fn func(S) R) []R {
result := make([]R, 0, len(s))
for _, v := range s {
result = append(result, fn(v))
}
return result
}
若只需要转换满足条件的元素,可先过滤再转换:
func SliceTransWithFilter[S, R any](s []S, fn func(S) (R, bool)) []R {
result := make([]R, 0, len(s))
for _, v := range s {
if r, ok := fn(v); ok {
result = append(result, r)
}
}
return result
}
调用
package test
import (
"fmt"
"testing"
"xh-control-ws/utils"
)
// 普通的测试
func Test02(t *testing.T) {
var nameList []string
nameList = append(nameList, "张三", "李四", "王五")
result := utils.SliceTrans(nameList, func(item string) string {
return item + "同学"
})
fmt.Println(result)
}
累计
对切片中的元素累计,获取一个最终结果:
func SliceAccum[S, R any](init R, s []S, fn func(last R, ele S) R) R {
result := init
for _, v := range s {
result = fn(result, v)
}
return result
}
字典 map
过滤
方法
func MapFilter[K comparable, V any](m map[K]V, fn func(key K, value V) bool) map[K]V {
result := make(map[K]V, len(m))
for k, v := range m {
if fn(k, v) {
result[k] = v
}
}
return result
}
调用
package test
import (
"fmt"
"testing"
"xh-control-ws/utils"
)
// 普通的测试
func Test01(t *testing.T) {
userinfo := map[string]string{"name": "xiaoming"}
userinfo["name"] = "xiaohong"
userinfo["age"] = "18"
result := utils.MapFilter(userinfo, func(key string, value string) bool {
return key == "name"
})
fmt.Println(result)
}
结果
map[name:xiaohong]
转换
方法
func MapTrans[K comparable, V, R any](m map[K]V, fn func(key K, value V) (R, bool)) map[K]R {
result := make(map[K]R, len(m))
for k, v := range m {
if r, ok := fn(k, v); ok {
result[k] = r
}
}
return result
}
掉用
package test
import (
"fmt"
"strings"
"testing"
"xh-control-ws/utils"
)
// 普通的测试
func Test01(t *testing.T) {
userinfo := map[string]string{"name": "xiaoming"}
userinfo["name"] = "xiaohong"
userinfo["age"] = "18"
result := utils.MapTrans(userinfo, func(key string, value string) (string, bool) {
if key == "name" {
return strings.ToUpper(value), true
} else {
return value + "岁", true
}
})
fmt.Println(result)
}
结果
map[age:18岁 name:XIAOHONG]
其中返回值中的bool,代表对应的key是否保留。