实现Slice的 过滤/聚合/映射 函数

发布时间 2023-10-22 18:45:23作者: hao32

一:前言

自从Golang 1.18支持泛型以来,编写泛型算法就变得方便了

下面的代码展示了如何实现Golang Slice的过滤/聚合/映射函数。代码很简单,就不多做解释了

二:函数实现

1. 过滤函数 SliceFilter

该函数会对数组的每一个元素执行filterFun,若filterFun返回true则将该元素添加至新数组

func SliceFilter[T any](list []T, filterFun func(T) (bool, error)) (result []T, err error) {
	var ok bool
	for _, item := range list {
		ok, err = filterFun(item)
		if err != nil {
			return
		}
		if ok {
			result = append(result, item)
		}
	}
	return
}

2. 聚合函数 SliceReduce

该函数会对数组的每一个元素执行reduceFun,然后获取将结果聚合

func SliceReduce[T any, M any](list []T, reduceFun func(M, T) (M, error), initValue M) (result M, err error) {
	result = initValue
	for _, item := range list {
		result, err = reduceFun(result, item)
		if err != nil {
			return
		}
	}
	return
}

3. 映射函数

该函数会对数组的每一个元素执行mapFun,然后生成新的数组

func SliceMap[T any, R any](list []T, mapFun func(T) (R, error)) (result []R, err error) {
	result = make([]R, len(list))
	for index, item := range list {
		result[index], err = mapFun(item)
		if err != nil {
			return
		}
	}
	return
}

三:调用方式

1. 使用示例

func main() {
	// 求出数组中的偶数
	srcSlice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	filterResult, err := SliceFilter(srcSlice, func(num int) (bool, error) {
		return num%2 == 0, nil
	})
	fmt.Printf("SliceFilter: %v, err=%v\n", filterResult, err)

	// 数组求和
	reduceResult, err := SliceReduce(srcSlice, func(curr int, num int) (int, error) {
		return curr + num, nil
	}, 0)
	fmt.Printf("reduceResult: %v, err=%v\n", reduceResult, err)

	// 数组元素*2
	mapResult, err := SliceMap(srcSlice, func(num int) (int, error) {
		return num * 2, nil
	})
	fmt.Printf("mapResult: %v, err=%v\n", mapResult, err)
}

2. 输出

SliceFilter: [2 4 6 8 10], err=<nil>
reduceResult: 55, err=<nil>
mapResult: [2 4 6 8 10 12 14 16 18 20], err=<nil>