Skip to content

Commit e77d876

Browse files
committed
Improved sorting functions
1 parent ff359e0 commit e77d876

File tree

2 files changed

+102
-18
lines changed

2 files changed

+102
-18
lines changed

fieldset.go

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ func (f *FieldSetType) addField(field fields.FieldInterface) *FieldSetType {
128128
//Sort("field1:1,field2:2") or Sort("field1:1","field2:2")
129129
func (f *FieldSetType) Sort(sortList ...string) *FieldSetType {
130130
size := len(f.fields)
131+
var endIdx int = size - 1
131132
var sortSlice []string
132133
if len(sortList) == 1 {
133134
sortSlice = strings.Split(sortList[0], ",")
@@ -140,18 +141,21 @@ func (f *FieldSetType) Sort(sortList ...string) *FieldSetType {
140141
fieldName := ni[0]
141142
if len(ni) > 1 {
142143
if ni[1] == "last" {
143-
index = size - 1
144+
index = endIdx
144145
} else if idx, err := strconv.Atoi(ni[1]); err != nil {
145146
continue
146147
} else {
147-
index = idx
148+
if idx >= 0 {
149+
index = idx
150+
} else {
151+
index = endIdx + idx
152+
}
153+
148154
}
149155
}
150156
if oldIndex, ok := f.fieldMap[fieldName]; ok {
151157
if oldIndex != index && size > index {
152-
f.fields[oldIndex], f.fields[index] = f.fields[index], f.fields[oldIndex]
153-
f.fieldMap[f.fields[index].Name()] = index
154-
f.fieldMap[f.fields[oldIndex].Name()] = oldIndex
158+
f.sortFields(index, oldIndex, endIdx, size)
155159
}
156160
}
157161
index++
@@ -161,14 +165,13 @@ func (f *FieldSetType) Sort(sortList ...string) *FieldSetType {
161165

162166
func (f *FieldSetType) Sort2Last(fieldsName ...string) *FieldSetType {
163167
size := len(f.fields)
164-
var index int = size - 1
168+
var endIdx int = size - 1
169+
var index int = endIdx
165170
for n := len(fieldsName) - 1; n >= 0; n-- {
166171
fieldName := fieldsName[n]
167172
if oldIndex, ok := f.fieldMap[fieldName]; ok {
168173
if oldIndex != index && index >= 0 {
169-
f.fields[oldIndex], f.fields[index] = f.fields[index], f.fields[oldIndex]
170-
f.fieldMap[f.fields[index].Name()] = index
171-
f.fieldMap[f.fields[oldIndex].Name()] = oldIndex
174+
f.sortFields(index, oldIndex, endIdx, size)
172175
}
173176
}
174177
index--
@@ -225,3 +228,42 @@ func (f *FieldSetType) Enable() *FieldSetType {
225228
f.RemoveTag("disabled")
226229
return f
227230
}
231+
232+
func (f *FieldSetType) sortFields(index, oldIndex, endIdx, size int) {
233+
234+
var newFields []fields.FieldInterface = make([]fields.FieldInterface, 0)
235+
var oldFields []fields.FieldInterface = make([]fields.FieldInterface, size)
236+
copy(oldFields, f.fields)
237+
var min, max int
238+
if index > oldIndex {
239+
//[ ][I][ ][ ][ ][ ] I:oldIndex=1
240+
//[ ][ ][ ][ ][I][ ] I:index=4
241+
if oldIndex > 0 {
242+
newFields = oldFields[0:oldIndex]
243+
}
244+
newFields = append(newFields, oldFields[oldIndex+1:index+1]...)
245+
newFields = append(newFields, f.fields[oldIndex])
246+
if index+1 <= endIdx {
247+
newFields = append(newFields, f.fields[index+1:]...)
248+
}
249+
min = oldIndex
250+
max = index
251+
} else {
252+
//[ ][ ][ ][ ][I][ ] I:oldIndex=4
253+
//[ ][I][ ][ ][ ][ ] I:index=1
254+
if index > 0 {
255+
newFields = oldFields[0:index]
256+
}
257+
newFields = append(newFields, oldFields[oldIndex])
258+
newFields = append(newFields, f.fields[index:oldIndex]...)
259+
if oldIndex+1 <= endIdx {
260+
newFields = append(newFields, f.fields[oldIndex+1:]...)
261+
}
262+
min = index
263+
max = oldIndex
264+
}
265+
for i := min; i <= max; i++ {
266+
f.fieldMap[newFields[i].Name()] = i
267+
}
268+
f.fields = newFields
269+
}

utils.go

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,23 +221,27 @@ func (f *Form) Sort(sortList ...string) *Form {
221221
sortSlice = sortList
222222
}
223223
var index int
224+
var endIdx int = size - 1
225+
224226
for _, nameIndex := range sortSlice {
225227
ni := strings.Split(nameIndex, ":")
226228
fieldName := ni[0]
227229
if len(ni) > 1 {
228230
if ni[1] == "last" {
229-
index = size - 1
231+
index = endIdx
230232
} else if idx, err := strconv.Atoi(ni[1]); err != nil {
231233
continue
232234
} else {
233-
index = idx
235+
if idx >= 0 {
236+
index = idx
237+
} else {
238+
index = size + idx
239+
}
234240
}
235241
}
236242
if oldIndex, ok := f.fieldMap[fieldName]; ok {
237243
if oldIndex != index && size > index {
238-
f.fields[oldIndex], f.fields[index] = f.fields[index], f.fields[oldIndex]
239-
f.fieldMap[f.fields[index].Name()] = index
240-
f.fieldMap[f.fields[oldIndex].Name()] = oldIndex
244+
f.sortFields(index, oldIndex, endIdx, size)
241245
}
242246
}
243247
index++
@@ -247,17 +251,55 @@ func (f *Form) Sort(sortList ...string) *Form {
247251

248252
func (f *Form) Sort2Last(fieldsName ...string) *Form {
249253
size := len(f.fields)
250-
var index int = size - 1
254+
var endIdx int = size - 1
255+
var index int = endIdx
251256
for n := len(fieldsName) - 1; n >= 0; n-- {
252257
fieldName := fieldsName[n]
253258
if oldIndex, ok := f.fieldMap[fieldName]; ok {
254259
if oldIndex != index && index >= 0 {
255-
f.fields[oldIndex], f.fields[index] = f.fields[index], f.fields[oldIndex]
256-
f.fieldMap[f.fields[index].Name()] = index
257-
f.fieldMap[f.fields[oldIndex].Name()] = oldIndex
260+
f.sortFields(index, oldIndex, endIdx, size)
258261
}
259262
}
260263
index--
261264
}
262265
return f
263266
}
267+
268+
func (f *Form) sortFields(index, oldIndex, endIdx, size int) {
269+
270+
var newFields []FormElement = make([]FormElement, 0)
271+
var oldFields []FormElement = make([]FormElement, size)
272+
copy(oldFields, f.fields)
273+
var min, max int
274+
if index > oldIndex {
275+
//[ ][I][ ][ ][ ][ ] I:oldIndex=1
276+
//[ ][ ][ ][ ][I][ ] I:index=4
277+
if oldIndex > 0 {
278+
newFields = oldFields[0:oldIndex]
279+
}
280+
newFields = append(newFields, oldFields[oldIndex+1:index+1]...)
281+
newFields = append(newFields, f.fields[oldIndex])
282+
if index+1 <= endIdx {
283+
newFields = append(newFields, f.fields[index+1:]...)
284+
}
285+
min = oldIndex
286+
max = index
287+
} else {
288+
//[ ][ ][ ][ ][I][ ] I:oldIndex=4
289+
//[ ][I][ ][ ][ ][ ] I:index=1
290+
if index > 0 {
291+
newFields = oldFields[0:index]
292+
}
293+
newFields = append(newFields, oldFields[oldIndex])
294+
newFields = append(newFields, f.fields[index:oldIndex]...)
295+
if oldIndex+1 <= endIdx {
296+
newFields = append(newFields, f.fields[oldIndex+1:]...)
297+
}
298+
min = index
299+
max = oldIndex
300+
}
301+
for i := min; i <= max; i++ {
302+
f.fieldMap[newFields[i].Name()] = i
303+
}
304+
f.fields = newFields
305+
}

0 commit comments

Comments
 (0)