在《 泛型约束与集合Set实现》中,介绍了泛型使用;通过泛型可方便地扩展一些常用功能。
slices
切片slice是go中常用的结构,在切片中查找满足一定条件的元素集以及转换是常用的功能。
过滤filter
通过一个函数参数来过滤所需的元素,只有满足条件元素才返回到结果集中:
func FilterSlice[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
}
判空也是常用的功能,获取所有非空集(通过FilterSlice可方便实现):
func NonNilSlice[T any](s []*T) []*T {
return FilterSlice(s, func(t *T) bool {
return t != nil
})
}
转换Transfer
通过一个转换函数,可方便地把原切片转换为新的切片:
func TransSlice[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 TransSliceWithFilter[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
}
累计Accumulate
对切片中的元素累计,获取一个最终结果:
func AccumSlice[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
}
maps
同理,可对map进行扩展;只是map中键的约束需要使用comparable类型:
func FilterMap[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
}
func TransMap[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
}