]> Cypherpunks.ru repositories - gostls13.git/blob - src/sort/example_keys_test.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / sort / example_keys_test.go
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package sort_test
6
7 import (
8         "fmt"
9         "sort"
10 )
11
12 // A couple of type definitions to make the units clear.
13 type earthMass float64
14 type au float64
15
16 // A Planet defines the properties of a solar system object.
17 type Planet struct {
18         name     string
19         mass     earthMass
20         distance au
21 }
22
23 // By is the type of a "less" function that defines the ordering of its Planet arguments.
24 type By func(p1, p2 *Planet) bool
25
26 // Sort is a method on the function type, By, that sorts the argument slice according to the function.
27 func (by By) Sort(planets []Planet) {
28         ps := &planetSorter{
29                 planets: planets,
30                 by:      by, // The Sort method's receiver is the function (closure) that defines the sort order.
31         }
32         sort.Sort(ps)
33 }
34
35 // planetSorter joins a By function and a slice of Planets to be sorted.
36 type planetSorter struct {
37         planets []Planet
38         by      func(p1, p2 *Planet) bool // Closure used in the Less method.
39 }
40
41 // Len is part of sort.Interface.
42 func (s *planetSorter) Len() int {
43         return len(s.planets)
44 }
45
46 // Swap is part of sort.Interface.
47 func (s *planetSorter) Swap(i, j int) {
48         s.planets[i], s.planets[j] = s.planets[j], s.planets[i]
49 }
50
51 // Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
52 func (s *planetSorter) Less(i, j int) bool {
53         return s.by(&s.planets[i], &s.planets[j])
54 }
55
56 var planets = []Planet{
57         {"Mercury", 0.055, 0.4},
58         {"Venus", 0.815, 0.7},
59         {"Earth", 1.0, 1.0},
60         {"Mars", 0.107, 1.5},
61 }
62
63 // ExampleSortKeys demonstrates a technique for sorting a struct type using programmable sort criteria.
64 func Example_sortKeys() {
65         // Closures that order the Planet structure.
66         name := func(p1, p2 *Planet) bool {
67                 return p1.name < p2.name
68         }
69         mass := func(p1, p2 *Planet) bool {
70                 return p1.mass < p2.mass
71         }
72         distance := func(p1, p2 *Planet) bool {
73                 return p1.distance < p2.distance
74         }
75         decreasingDistance := func(p1, p2 *Planet) bool {
76                 return distance(p2, p1)
77         }
78
79         // Sort the planets by the various criteria.
80         By(name).Sort(planets)
81         fmt.Println("By name:", planets)
82
83         By(mass).Sort(planets)
84         fmt.Println("By mass:", planets)
85
86         By(distance).Sort(planets)
87         fmt.Println("By distance:", planets)
88
89         By(decreasingDistance).Sort(planets)
90         fmt.Println("By decreasing distance:", planets)
91
92         // Output: By name: [{Earth 1 1} {Mars 0.107 1.5} {Mercury 0.055 0.4} {Venus 0.815 0.7}]
93         // By mass: [{Mercury 0.055 0.4} {Mars 0.107 1.5} {Venus 0.815 0.7} {Earth 1 1}]
94         // By distance: [{Mercury 0.055 0.4} {Venus 0.815 0.7} {Earth 1 1} {Mars 0.107 1.5}]
95         // By decreasing distance: [{Mars 0.107 1.5} {Earth 1 1} {Venus 0.815 0.7} {Mercury 0.055 0.4}]
96 }