[go]泛型扩展切片与map(filter与transfer)

本文介绍了Go语言中对切片的常见操作,包括过滤filter、转换transfer、累计accumulate以及对map的类似操作。通过提供泛型约束,实现了针对任意类型的切片和map进行条件过滤、类型转换和元素累计的功能,有助于提高代码的灵活性和可复用性。
摘要由CSDN通过智能技术生成


在《 泛型约束与集合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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值