筚路蓝缕,以启山林。抚有蛮夷,以属华夏。不鸣则已,一鸣惊人。
                                                                                                          ——《左传`宣公十二年》

 

之前有人(面试官)提过这个问题,刚想到要不总结一下,顺手来实现下看看。

map遍历数据本身就是无序的,我们不能直接对map本身的存储结构进行直接操作,但可在它所存储的数据上做手脚。

多个情况的解决方案如下,直接上代码

func main() {
	m := make(map[int]string)
	m[1] = "A"
	m[5] = "B"
	m[2] = "B"
	m[3] = "C"
	m[4] = "A"

	for k, v := range m {
		fmt.Println(k, v) // 多次运行,每次输出的都是key无序的
	}

	// 输出map中的数据,按key排序
	count := len(m)
	keySlice := make([]int, 0, count)    // 用于单独存放key的切片,按key时只看该行即可
	valSlice := make([]string, 0, count) // 用于单独存放value值的切片
	valMap := make(map[string][]int)     // 用于存放原map的value-key映射(以value获取key集合),key值相同时对应多个value值
	for k := range m {
		keySlice = append(keySlice, k) // 按key时只看该行即可
		valSlice = append(valSlice, m[k])
		if _, ok := valMap[m[k]]; ok {
			valMap[m[k]] = append(valMap[m[k]], k)
			continue
		}
		valMap[m[k]] = []int{k}
	}

	sort.Ints(keySlice)
	fmt.Println("获取按key排序后数据:")
	for _, v := range keySlice {
		fmt.Println(v, m[v])
	}

	// 按value排序,方式1
	sort.Strings(valSlice)
	fmt.Println("获取按value排序后数据(只需要value时):")
	for _, v := range valSlice {
		fmt.Println(v)
	}

	fmt.Println("获取按value排序后数据(key、value都需要时):")
	for _, v := range valSlice {
		if _, ok := valMap[v]; ok {
			fmt.Println(valMap[v], v) // 如要继续分别按每个key输出,可以if len(valMap[v]) > 1 {...}进行判断操作
			delete(valMap, v)
			continue
		}
	}

	// 按value排序,方式2
	sortList, index := make(KVList, count), 0
	for k, v := range m {
		sortList[index] = KV{k, v}
		if index < count {
			index++
		}
	}

	sort.Sort(sortList)
	fmt.Println("获取按value排序后数据(key、value都需要时):")
	for _, v := range sortList {
		fmt.Println(v.K,m[v.K])
	}
}

// 把map的每一对键值作为对象存起来
type KV struct {
	K int
	V string
}

type KVList []KV

func (l KVList) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}

func (l KVList) Len() int {
	return len(l)
}

func (l KVList) Less(i, j int) bool {
	return l[i].V < l[j].V
}


控制台:

1 A
5 B
2 B
3 C
4 A
获取按key排序后数据:
1 A
2 B
3 C
4 A
5 B
获取按value排序后数据(只需要value时):
A
A
B
B
C
获取按value排序后数据(key、value都需要时):
[1 4] A
[5 2] B
[3] C
获取按value排序后数据(key、value都需要时):
4 A
1 A
5 B
2 B
3 C

当然,排序时也可自己写排序方法代替sort库的Sort方法。