Golang分片和泛型Map排序

267 阅读2分钟

自定义类型的列表排序

方法:对列表实现sort.Interface接口要求的所有方法 Len() int

Less(i,j int)bool

Swap(i,j int)

type CostComparisonOverview []handler.AliyunCostComparisonOverviewResponse

// 实现sort.Interface接口的Len方法
func (list CostComparisonOverview) Len() int {
	return len(list)
}

// 实现sort.Interface接口的Less方法
func (list CostComparisonOverview) Less(i, j int) bool {
	return list[i].ProductCode > list[j].ProductCode
}

// 实现sort.Interface接口的Swap方法
func (list CostComparisonOverview) Swap(i, j int) {
	list[i], list[j] = list[j], list[i]
}

实现了sort.Interface的所有方法

sort.Sort

image.png

image.png

这里可以看到有123个实现

这里type Interface interface;其中第一个Interface为 类型名称

第二个 interface 为类型:接口

image.png

执行排序

image.png

// 对列表进行排序
var list CostComparisonOverview

list = overview.Record

sort.Sort(list)

这里sort.Sort

其中sort为package,Sort为package sort的函数

入参类型为 sort.Interface,接口类型,同时声明需要实现 Len Less Swap方法

这里CostComparisonOverview实现了sort.Interface接口要求的所有方法

而 这里的变量list「类型为CostComparisonOverview」 绑定了 Len Less Swap方法,所以符合入参类型约束;因此,可以调用sorr.Sort(list)方法进行排序

对Map Key正向反向排序

实际场景中,经常需要对Map的Key进行升序、降序排列

但因为 Golang Map无序、而分片有序;所以无法对Map 的Key进行排序直接返回按照Key排序的Map

所以只能返回排序后的Key分片,再自行处理

如何实现对Map的泛型Key进行排序

声明嵌套泛型类型

type InfraInt interface {
	int | int8 | int16 | int32 | int64
}

type InfraUnit interface {
	uint | uint8 | uint16 | uint32
}

type InfraFloat interface {
	float32 | float64
}

type InfraNum interface {
	InfraInt | InfraUnit | InfraFloat
}

type InfraString interface {
	string
}

泛型分片Map的Key排序

type MapObj[Key InfraString | InfraNum, Value InfraString | InfraNum] map[Key]Value

type KeysObj[T InfraString | InfraNum] []T

func (s KeysObj[T]) Len() int {
	return len(s)
}

func (s KeysObj[T]) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func (s KeysObj[T]) Less(i, j int) bool {
	return s[i] > s[j]
}

正向、反向排序泛型Map的Key

// 对泛型Map的Key升序排列,并返回排列后有序Map Key切片
func MapKeySortByAsc[Key InfraString | InfraNum, Value InfraString | InfraNum](m map[Key]Value) []Key {

	keys := KeysObj[Key]{}

	for key := range m {
		keys = append(keys, key)
	}

	sort.Sort(keys)

	return keys
}

// 对泛型Map的Key降序排列,并返回排列后有序Map Key切片
func MapKeySortByDesc[Key InfraString | InfraNum, Value InfraString | InfraNum](m map[Key]Value) []Key {

	keys := KeysObj[Key]{}

	for key := range m {
		keys = append(keys, key)
	}

	sort.Sort(sort.Reverse(keys))

	return keys
}

使用

func TestMapSort(t *testing.T) {
	m := map[string]string{
		"asdf1":     "1",
		"12sadfsd3": "1asdf",
		"a1sadf":    "1",
		"21asdz":    "1",
		"s1dsaf":    "1",
		"2asd":      "2",
	}
	fmt.Println(m)
	fmt.Println(util.MapKeySortByAsc(m))
	fmt.Println(util.MapKeySortByDesc(m))

	m1 := map[int]string{
		1:   "1",
		123: "1asdf",
		21:  "1",
		2:   "2",
	}
	fmt.Println(m1)
	fmt.Println(util.MapKeySortByAsc(m1))
	fmt.Println(util.MapKeySortByDesc(m1))
}

输出结果

image.png