1
2
3
4
5
6
7
8
9 package fmtsort
10
11 import (
12 "reflect"
13 "sort"
14 )
15
16
17
18
19
20
21 type SortedMap struct {
22 Key []reflect.Value
23 Value []reflect.Value
24 }
25
26 func (o *SortedMap) Len() int { return len(o.Key) }
27 func (o *SortedMap) Less(i, j int) bool { return compare(o.Key[i], o.Key[j]) < 0 }
28 func (o *SortedMap) Swap(i, j int) {
29 o.Key[i], o.Key[j] = o.Key[j], o.Key[i]
30 o.Value[i], o.Value[j] = o.Value[j], o.Value[i]
31 }
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 func Sort(mapValue reflect.Value) *SortedMap {
52 if mapValue.Type().Kind() != reflect.Map {
53 return nil
54 }
55
56
57
58 n := mapValue.Len()
59 key := make([]reflect.Value, 0, n)
60 value := make([]reflect.Value, 0, n)
61 iter := mapValue.MapRange()
62 for iter.Next() {
63 key = append(key, iter.Key())
64 value = append(value, iter.Value())
65 }
66 sorted := &SortedMap{
67 Key: key,
68 Value: value,
69 }
70 sort.Stable(sorted)
71 return sorted
72 }
73
74
75
76
77
78 func compare(aVal, bVal reflect.Value) int {
79 aType, bType := aVal.Type(), bVal.Type()
80 if aType != bType {
81 return -1
82 }
83 switch aVal.Kind() {
84 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
85 a, b := aVal.Int(), bVal.Int()
86 switch {
87 case a < b:
88 return -1
89 case a > b:
90 return 1
91 default:
92 return 0
93 }
94 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
95 a, b := aVal.Uint(), bVal.Uint()
96 switch {
97 case a < b:
98 return -1
99 case a > b:
100 return 1
101 default:
102 return 0
103 }
104 case reflect.String:
105 a, b := aVal.String(), bVal.String()
106 switch {
107 case a < b:
108 return -1
109 case a > b:
110 return 1
111 default:
112 return 0
113 }
114 case reflect.Float32, reflect.Float64:
115 return floatCompare(aVal.Float(), bVal.Float())
116 case reflect.Complex64, reflect.Complex128:
117 a, b := aVal.Complex(), bVal.Complex()
118 if c := floatCompare(real(a), real(b)); c != 0 {
119 return c
120 }
121 return floatCompare(imag(a), imag(b))
122 case reflect.Bool:
123 a, b := aVal.Bool(), bVal.Bool()
124 switch {
125 case a == b:
126 return 0
127 case a:
128 return 1
129 default:
130 return -1
131 }
132 case reflect.Pointer, reflect.UnsafePointer:
133 a, b := aVal.Pointer(), bVal.Pointer()
134 switch {
135 case a < b:
136 return -1
137 case a > b:
138 return 1
139 default:
140 return 0
141 }
142 case reflect.Chan:
143 if c, ok := nilCompare(aVal, bVal); ok {
144 return c
145 }
146 ap, bp := aVal.Pointer(), bVal.Pointer()
147 switch {
148 case ap < bp:
149 return -1
150 case ap > bp:
151 return 1
152 default:
153 return 0
154 }
155 case reflect.Struct:
156 for i := 0; i < aVal.NumField(); i++ {
157 if c := compare(aVal.Field(i), bVal.Field(i)); c != 0 {
158 return c
159 }
160 }
161 return 0
162 case reflect.Array:
163 for i := 0; i < aVal.Len(); i++ {
164 if c := compare(aVal.Index(i), bVal.Index(i)); c != 0 {
165 return c
166 }
167 }
168 return 0
169 case reflect.Interface:
170 if c, ok := nilCompare(aVal, bVal); ok {
171 return c
172 }
173 c := compare(reflect.ValueOf(aVal.Elem().Type()), reflect.ValueOf(bVal.Elem().Type()))
174 if c != 0 {
175 return c
176 }
177 return compare(aVal.Elem(), bVal.Elem())
178 default:
179
180 panic("bad type in compare: " + aType.String())
181 }
182 }
183
184
185
186
187
188
189 func nilCompare(aVal, bVal reflect.Value) (int, bool) {
190 if aVal.IsNil() {
191 if bVal.IsNil() {
192 return 0, true
193 }
194 return -1, true
195 }
196 if bVal.IsNil() {
197 return 1, true
198 }
199 return 0, false
200 }
201
202
203 func floatCompare(a, b float64) int {
204 switch {
205 case isNaN(a):
206 return -1
207 case isNaN(b):
208 return 1
209 case a < b:
210 return -1
211 case a > b:
212 return 1
213 }
214 return 0
215 }
216
217 func isNaN(a float64) bool {
218 return a != a
219 }
220
View as plain text