Skip to content

Instantly share code, notes, and snippets.

@infogulch
Last active May 6, 2016 23:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save infogulch/5db15e5ae5cf073f1088033ba4c714fb to your computer and use it in GitHub Desktop.
Save infogulch/5db15e5ae5cf073f1088033ba4c714fb to your computer and use it in GitHub Desktop.
How to design a Go slice type that needs to be sortable in many ways.
// How to design a Go slice type that needs to be sortable in many ways.
package main
import (
"fmt"
"sort"
)
type data struct {
i int
s string
}
type dataless func(data, data) bool
func (fn1 dataless) Then(fn2 dataless) dataless {
return func(a, b data) bool {
return fn1(a, b) || (!fn1(b, a) && fn2(a, b))
}
}
type datas []data
func (d datas) Len() int { return len(d) }
func (d datas) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
func (d datas) By(fn dataless) datasorter { return datasorter{d, fn} }
type datasorter struct {
datas
less dataless
}
func (s datasorter) Less(i, j int) bool { return s.less(s.datas[i], s.datas[j]) }
func main() {
x := datas{{3, "b"}, {4, "c"}, {1, "d"}, {2, "a"}}
fmt.Printf("Before: %v\n", x)
strings := func(a, b data) bool { return a.s < b.s }
sort.Sort(x.By(strings))
fmt.Printf("Sorted by string: %v\n", x)
sort.Sort(x.By(func(a, b data) bool {
return a.i < b.i
}))
fmt.Printf("Sorted by int: %v\n", x)
var evens dataless = func(a, b data) bool { return a.i&1 < b.i&1 }
sort.Sort(x.By(evens))
fmt.Printf("Sorted by evens: %v\n", x)
sort.Sort(x.By(evens.Then(strings)))
fmt.Printf("Sorted by evens then strings: %v\n", x)
}
// Output:
//
// Before: [{3 b} {4 c} {1 d} {2 a}]
// Sorted by string: [{2 a} {3 b} {4 c} {1 d}]
// Sorted by int: [{1 d} {2 a} {3 b} {4 c}]
// Sorted by evens: [{2 a} {4 c} {1 d} {3 b}]
// Sorted by evens then strings: [{2 a} {4 c} {3 b} {1 d}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment