go泛型体验 map有序化(可比较key,返回有序key值)

2024-05-20 16:47:55 浏览数 (2)

golang 即将支持泛型,我们能用泛型做些什么呢?本文探索泛型的一个使用场景,go 的 map 进行遍历是无序的,我们往往需要按照顺序对可排序类型的key进行 map 进行有序遍历

1. go的map 是无需的,我们经常需要按照key 的有序输出。

2. 并不是所有的key 都能比较,只要类型 可以进行 == 操作,就可以作为key,所以有序输出只在可比较的类型成立

使用泛型功能实现一个map有序化的函数

请大佬不吝赐教

代码语言:go复制
package main

import (
	"fmt"
	"reflect"
)

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

func sortMapWithValue[T mapKey](m map[T]any) []struct {
	key   T
	value any
} {
	var kList []T
	for k := range m {
		kList = append(kList, k)
	}
	for i := 0; i < len(kList); i   {
		for j := 0; j < len(kList); j   {
			if kList[i] < kList[j] {
				kList[i], kList[j] = kList[j], kList[i]
			}
		}
	}
	var list []struct {
		key   T
		value any
	}
	for _, v := range kList {
		list = append(list, struct {
			key   T
			value any
		}{key: v, value: m[v]})
	}
	return list
}

func sortMap[T mapKey](m map[T]any) (kList []T) {
	for k := range m {
		kList = append(kList, k)
	}
	for i := 0; i < len(kList); i   {
		for j := 0; j < len(kList); j   {
			if kList[i] < kList[j] {
				kList[i], kList[j] = kList[j], kList[i]
			}
		}
	}
	return
}

func main() {
	intMap()
	strMap()
}
func strMap() {
	strMaps := []map[string]any{
		{
			"a": 1, "b": 2, "c": 3, "d": 4,
		},
		{
			"a": "a", "b": "b", "c": "c", "d": "d",
		},
	}
	for _, v := range strMaps {
		dest := sortMapWithValue(v)
		fmt.Println(reflect.TypeOf(dest), reflect.ValueOf(dest))
		for _, v := range dest {
			fmt.Println(v.key, reflect.TypeOf(v.key), v.value, reflect.TypeOf(v.value))
		}
		dest1 := sortMap(v)
		fmt.Println(reflect.TypeOf(dest1), reflect.ValueOf(dest1))
		for _, v1 := range dest1 {
			fmt.Println(v1, reflect.TypeOf(v1), v[v1], reflect.TypeOf(v[v1]))
		}
	}
}

func intMap() {
	intMaps := []map[int]any{
		{
			1: "a", 2: "b", 3: "c", 4: "d",
		},
		{
			1: 1, 2: 2, 3: 3, 4: 4,
		},
	}
	for _, v := range intMaps {
		dest := sortMapWithValue(v)
		fmt.Println(reflect.TypeOf(dest), reflect.ValueOf(dest))
		for _, v1 := range dest {
			fmt.Println(v1.key, reflect.TypeOf(v1.key), v1.value, reflect.TypeOf(v1.value))
		}
		dest1 := sortMap(v)
		fmt.Println(reflect.TypeOf(dest1), reflect.ValueOf(dest1))
		for _, v1 := range dest1 {
			fmt.Println(v1, reflect.TypeOf(v1), v[v1], reflect.TypeOf(v[v1]))
		}
	}
}

最后,

github.com/samber/lo 这个库 有很多脚手架函数,大部分采用了泛型。可以学习学习

0 人点赞