go语言函数式泛型之Map、Reduce、 filter示例代码
Go语言的1.17版本正式支持泛型,现在就来体验一下Go的泛型编程
函数式编程的三大件map() 、 reduce() 、filter(),下面看一下泛型版本实现
泛型Map
func gMap[T1 any, T2 any] (arr []T1, f func(T1) T2) []T2 {
result := make([]T2, len(arr))
for i, elem := range arr {
result[i] = f(elem)
}
return result
}
在上面的这个 map函数中我使用了两个类型 – T1 和 T2 ,
T1 – 是需要处理数据的类型
T2 – 是处理后的数据类型
T1 和 T2 可以一样,也可以不一样。
我们还有一个函数参数 – func(T1) T2 意味着,进入的是 T1 类型的,出来的是 T2 类型的。
然后,整个函数返回的是一个 []T2
好的,我们来看一下怎么使用这个map函数:
nums := []int {0,1,2,3,4,5,6,7,8,9}
squares := gMap(nums, func (elem int) int {
return elem * elem
})
print(squares) //0 1 4 9 16 25 36 49 64 81
strs := []string{"Hao", "Chen", "MegaEase"}
upstrs := gMap(strs, func(s string) string {
return strings.ToUpper(s)
})
print(upstrs) // HAO CHEN MEGAEASE
dict := []string{"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}
strs = gMap(nums, func (elem int) string {
return dict[elem]
})
print(strs) // 零 壹 贰 叁 肆 伍 陆 柒 捌 玖
泛型 Reduce
接下来,我们再来看一下我们的Reduce函数,reduce函数是把一堆数据合成一个。
func gReduce[T1 any, T2 any] (arr []T1, init T2, f func(T2, T1) T2) T2 {
result := init
for _, elem := range arr {
result = f(result, elem)
}
return result
}
函数实现起来很简单,但是感觉不是很优雅。
也是有两个类型 T1 和 T2,前者是输出数据的类型,后者是佃出数据的类型。
因为要合成一个数据,所以需要有这个数据的初始值 init,是 T2 类型
而自定义函数 func(T2, T1) T2,会把这个init值传给用户,然后用户处理完后再返回出来。
下面是一个使用上的示例——求一个数组的和
nums := []int {0,1,2,3,4,5,6,7,8,9}
sum := gReduce(nums, 0, func (result, elem int) int {
return result + elem
})
fmt.Printf("Sum = %d \n", sum)
泛型 filter
filter函数主要是用来做过滤的,
把数据中一些符合条件(filter in)或是不符合条件(filter out)的数据过滤出来,
下面是相关的代码示例
func gFilter[T any] (arr []T, in bool, f func(T) bool) []T {
result := []T{}
for _, elem := range arr {
choose := f(elem)
if (in && choose) || (!in && !choose) {
result = append(result, elem)
}
}
return result
}
func gFilterIn[T any] (arr []T, f func(T) bool) []T {
return gFilter(arr, true, f)
}
func gFilterOut[T any] (arr []T, f func(T) bool) []T {
return gFilter(arr, false, f)
}
其中,用户需要提从一个 bool 的函数,我们会把数据传给用户,
然后用户只需要告诉我行还是不行,于是我们就会返回一个过滤好的数组给用户。
比如,我们想把数组中所有的奇数过滤出来
nums := []int {0,1,2,3,4,5,6,7,8,9}
odds := gFilterIn(nums, func (elem int) bool {
return elem % 2 == 1
})
print(odds)
相关文章