...

Source file src/sort/example_keys_test.go

Documentation: sort

		 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  }
		97  

View as plain text