1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| import ( "fmt" "sort" )
type Change struct { user string language string lines int }
type lessFunc func(p1, p2 *Change) bool
type multiSorter struct { changes []Change less []lessFunc }
func (ms *multiSorter) Len() int { return len(ms.changes) } func (ms *multiSorter) Swap(i, j int) { ms.changes[i], ms.changes[j] = ms.changes[j], ms.changes[i] }
func (ms *multiSorter) Less(i, j int) bool { p, q := &ms.changes[i], &ms.changes[j] var k int for k = 0; k < len(ms.less)-1; k++ { less := ms.less[k] switch { case less(p, q): return true case less(q, p): return false } } return ms.less[k](p, q) }
func (ms *multiSorter) Sort(changes []Change) { ms.changes = changes sort.Sort(ms) }
func OrderedBy(less ...lessFunc) *multiSorter { return &multiSorter{ less: less, } }
var changes = []Change{ {"gri", "Go", 100}, {"ken", "C", 150}, {"glenda", "Go", 200}, {"rsc", "Go", 200}, {"r", "Go", 100}, {"ken", "Go", 200}, {"dmr", "C", 100}, {"r", "C", 150}, {"gri", "Smalltalk", 80}, }
func main() { user := func(c1, c2 *Change) bool { return c1.user < c2.user } language := func(c1, c2 *Change) bool { return c1.language < c2.language } increasingLines := func(c1, c2 *Change) bool { return c1.lines < c2.lines } decreasingLines := func(c1, c2 *Change) bool { return increasingLines(c2, c1) }
OrderedBy(user).Sort(changes) fmt.Println("By user:", changes) OrderedBy(user, increasingLines).Sort(changes) fmt.Println("By user,<lines:", changes) OrderedBy(user, decreasingLines).Sort(changes) fmt.Println("By user,>lines:", changes) OrderedBy(language, increasingLines).Sort(changes) fmt.Println("By language,<lines:", changes) OrderedBy(language, increasingLines, user).Sort(changes) fmt.Println("By language,<lines,user:", changes) }
|