GOLANG 泛型 实现PHP数组操作方法

3 篇文章 0 订阅

github: https://github.com/EricJSanchez/php2go

package php2go

import (
	"reflect"
)

type Integer interface {
	uint | uint8 | uint16 | uint32 | uint64 | int | int8 | int16 | int32 | int64 | float32 | float64
}

type IntegerString interface {
	uint | uint8 | uint16 | uint32 | uint64 | int | int8 | int16 | int32 | int64 | float32 | float64 | string
}

// ArrayReverse 数组翻转
func ArrayReverse[T IntegerString](s []T) []T {
	l := len(s)
	r := make([]T, l)
	for i, ele := range s {
		r[l-i-1] = ele
	}
	return r
}

// ArrayColumn 获取二维数组中的某一列,组合成一维数组
func ArrayColumn[T IntegerString](s interface{}, col string) (retCol []T) {
	rv := reflect.ValueOf(s)
	ln := rv.Len()
	for i := 0; i < ln; i++ {
		tmpRv := rv.Index(i)
		value := tmpRv.FieldByName(col)
		if !value.IsValid() {
			panic("unknown field: " + col)
		}
		switch value.Kind() {
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64, reflect.String:
			value := value.Interface().(T)
			retCol = append(retCol, value)
		default:
			panic("unknown field: " + col)
			break
		}
	}
	return
}

// ArraySum 计算数组中某一列的和,一维数组时计算全部
func ArraySum[T Integer](s interface{}, col string) (sum T) {
	rv := reflect.ValueOf(s)
	ln := rv.Len()
	for i := 0; i < ln; i++ {
		tmpRv := rv.Index(i)
		// 一维数组,直接相加即可
		if col == "" {
			sum = sum + tmpRv.Interface().(T)
			continue
		}
		value := tmpRv.FieldByName(col)
		if !value.IsValid() {
			panic("unknown field: " + col)
			break
		}
		switch value.Kind() {
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64:
			value := value.Interface().(T)
			sum = sum + value
		default:
			panic("unknown field: " + col)
			break
		}
	}
	return
}

// ArrayUnique 数组去重,只限一维数组
func ArrayUnique[T IntegerString](s []T) (retData []T) {
	tmpMap := make(map[T]bool, len(s))
	for i := 0; i < len(s); i++ {
		// map去重
		if _, ok := tmpMap[s[i]]; ok != true {
			tmpMap[s[i]] = true
			retData = append(retData, s[i])
		}
	}
	return
}

// InArray 值是否存在
func InArray(needle interface{}, haystack interface{}) bool {
	val := reflect.ValueOf(haystack)
	switch val.Kind() {
	case reflect.Slice, reflect.Array:
		for i := 0; i < val.Len(); i++ {
			if reflect.DeepEqual(needle, val.Index(i).Interface()) {
				return true
			}
		}
	case reflect.Map:
		for _, k := range val.MapKeys() {
			if reflect.DeepEqual(needle, val.MapIndex(k).Interface()) {
				return true
			}
		}
	default:
		panic("haystack: haystack type muset be slice, array or map")
	}

	return false
}

// ArrayIntersect 数组交集,只限一维数组
func ArrayIntersect[T IntegerString](s1, s2 []T) (intersectArr []T) {
	mp := make(map[T]bool)
	for _, s := range s1 {
		if _, ok := mp[s]; !ok {
			mp[s] = true
		}
	}
	for _, s := range s2 {
		if _, ok := mp[s]; ok {
			intersectArr = append(intersectArr, s)
		}
	}
	return
}

// ArrayDiff 求差集,s1-s2 = s1去除s2在s1中存在的值,只限一维数组
func ArrayDiff[T IntegerString](s1, s2 []T) (diffArr []T) {
	temp := make(map[T]bool, len(s2))

	for _, val := range s2 {
		if _, ok := temp[val]; !ok {
			temp[val] = true
		}
	}

	for _, val := range s1 {
		if _, ok := temp[val]; !ok {
			diffArr = append(diffArr, val)
		}
	}
	return
}

// Max 求最大值
func Max[T IntegerString](s1 []T) (retVal T) {
	if len(s1) == 0 {
		return
	}
	retVal = s1[0]
	for _, val := range s1 {
		if val > retVal {
			retVal = val
		}
	}
	return
}

// Min 求最小值
func Min[T IntegerString](s1 []T) (retVal T) {
	if len(s1) == 0 {
		return
	}
	retVal = s1[0]
	for _, val := range s1 {
		if val < retVal {
			retVal = val
		}
	}
	return
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
golang泛型是一种通用类型的编程方式,可以在代码使用不特定具体类型来实现通用性。然而,目前的golang版本(截至2021年)并不直接支持泛型。 虽然golang没有原生的泛型支持,但可以通过接口方法实现类似的效果。在接口的定义,可以使用空接口类型(interface{})作为参数或返回类型。空接口类型可以接收任意类型的值。 在使用空接口类型作为接口方法的参数时,可以将任意类型值传递给该方法。在方法内部,可以使用类型断言将空接口类型转换成具体的类型,从而实现对不同类型的值的处理。这样可以实现一种类似泛型的效果,通过接口方法来处理不同类型的值。 示例代码如下: ```go package main import "fmt" type Generic interface { Process(interface{}) interface{} } type StringContainer struct{} func (sc StringContainer) Process(item interface{}) interface{} { str, ok := item.(string) if !ok { return "error: not a string" } return "string: " + str } type IntContainer struct{} func (ic IntContainer) Process(item interface{}) interface{} { num, ok := item.(int) if !ok { return "error: not an int" } return "int: " + fmt.Sprintf("%d", num) } func main() { strContainer := StringContainer{} intContainer := IntContainer{} strResult := strContainer.Process("hello") intResult := intContainer.Process(123) fmt.Println(strResult) // output: string: hello fmt.Println(intResult) // output: int: 123 } ``` 在上述示例,我们定义了一个`Generic`接口,该接口包含了一个`Process`方法,该方法接收一个空接口类型参数并返回一个空接口类型结果。然后我们定义了`StringContainer`和`IntContainer`两个结构体,并为它们实现了`Process`方法。在`Process`方法,我们使用类型断言将参数转换为具体的类型,然后进行相应的处理。最后在`main`函数,我们创建了`StringContainer`和`IntContainer`的实例,并调用其`Process`方法来处理不同类型的值。 通过接口方法的利用,我们可以实现类似泛型的效果。当然,这种方式并不是完全等同于原生的泛型特性,而是一种在golang模拟实现泛型方法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值