coinsort.gno
1.85 Kb · 68 lines
1// Package coinsort provides helpers to sort a slice of std.Coins using the
2// classic sort.Sort API (without relying on sort.Slice).
3//
4// Usage examples:
5//
6// coins := banker.GetCoins("g1....")
7//
8// // Ascending by balance
9// coinsort.SortByBalance(coins)
10//
11// // Custom order – largest balance first
12// coinsort.SortBy(coins, func(a, b std.Coin) bool {
13// return a.Amount > b.Amount // descending
14// })
15//
16// Note: when getting std.Coins from the banker, it's sorted by denom by default.
17package coinsort
18
19import (
20 "sort"
21 "std"
22)
23
24type ByAmount struct{ std.Coins }
25
26func (b ByAmount) Len() int { return len(b.Coins) }
27func (b ByAmount) Swap(i, j int) { b.Coins[i], b.Coins[j] = b.Coins[j], b.Coins[i] }
28func (b ByAmount) Less(i, j int) bool { return b.Coins[i].Amount < b.Coins[j].Amount }
29
30// SortByBalance sorts c in ascending order by Amount.
31//
32// coinsort.SortByBalance(myCoins)
33func SortByBalance(c std.Coins) {
34 sort.Sort(ByAmount{c})
35}
36
37// LessFunc defines the comparison function for SortBy. It must return true if
38// 'a' should come before 'b'.
39
40type LessFunc func(a, b std.Coin) bool
41
42// customSorter adapts a LessFunc to sort.Interface so we can keep using
43// sort.Sort (rather than sort.Slice).
44
45type customSorter struct {
46 coins std.Coins
47 less LessFunc
48}
49
50func (cs customSorter) Len() int { return len(cs.coins) }
51func (cs customSorter) Swap(i, j int) { cs.coins[i], cs.coins[j] = cs.coins[j], cs.coins[i] }
52func (cs customSorter) Less(i, j int) bool {
53 return cs.less(cs.coins[i], cs.coins[j])
54}
55
56// SortBy sorts c in place using the provided LessFunc.
57//
58// Example – descending by Amount:
59//
60// coinsort.SortBy(coins, func(a, b std.Coin) bool {
61// return a.Amount > b.Amount
62// })
63func SortBy(c std.Coins, less LessFunc) {
64 if less == nil {
65 return // nothing to do; keep original order
66 }
67 sort.Sort(customSorter{coins: c, less: less})
68}