package sort

import "sort"

Package sort 为切片和用户自定义集合提供排序原语。

Example
package main

import (
	"fmt"
	"sort"
)

type Person struct {
	Name string
	Age  int
}

func (p Person) String() string {
	return fmt.Sprintf("%s: %d", p.Name, p.Age)
}

// ByAge implements sort.Interface for []Person based on
// the Age field.
type ByAge []Person

func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }

func main() {
	people := []Person{
		{"Bob", 31},
		{"John", 42},
		{"Michael", 17},
		{"Jenny", 26},
	}

	fmt.Println(people)
	// There are two ways to sort a slice. First, one can define
	// a set of methods for the slice type, as with ByAge, and
	// call sort.Sort. In this first example we use that technique.
	sort.Sort(ByAge(people))
	fmt.Println(people)

	// The other way is to use sort.Slice with a custom Less
	// function, which can be provided as a closure. In this
	// case no methods are needed. (And if they exist, they
	// are ignored.) Here we re-sort in reverse order: compare
	// the closure with ByAge.Less.
	sort.Slice(people, func(i, j int) bool {
		return people[i].Age > people[j].Age
	})
	fmt.Println(people)

}

Output:

[Bob: 31 John: 42 Michael: 17 Jenny: 26]
[Michael: 17 Jenny: 26 Bob: 31 John: 42]
[John: 42 Bob: 31 Jenny: 26 Michael: 17]
Example (SortKeys)

Example_sortKeys demonstrates a technique for sorting a struct type using programmable sort criteria.

package main

import (
	"fmt"
	"sort"
)

// A couple of type definitions to make the units clear.
type earthMass float64
type au float64

// A Planet defines the properties of a solar system object.
type Planet struct {
	name     string
	mass     earthMass
	distance au
}

// By is the type of a "less" function that defines the ordering of its Planet arguments.
type By func(p1, p2 *Planet) bool

// Sort is a method on the function type, By, that sorts the argument slice according to the function.
func (by By) Sort(planets []Planet) {
	ps := &planetSorter{
		planets: planets,
		by:      by, // The Sort method's receiver is the function (closure) that defines the sort order.
	}
	sort.Sort(ps)
}

// planetSorter joins a By function and a slice of Planets to be sorted.
type planetSorter struct {
	planets []Planet
	by      func(p1, p2 *Planet) bool // Closure used in the Less method.
}

// Len is part of sort.Interface.
func (s *planetSorter) Len() int {
	return len(s.planets)
}

// Swap is part of sort.Interface.
func (s *planetSorter) Swap(i, j int) {
	s.planets[i], s.planets[j] = s.planets[j], s.planets[i]
}

// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
func (s *planetSorter) Less(i, j int) bool {
	return s.by(&s.planets[i], &s.planets[j])
}

var planets = []Planet{
	{"Mercury", 0.055, 0.4},
	{"Venus", 0.815, 0.7},
	{"Earth", 1.0, 1.0},
	{"Mars", 0.107, 1.5},
}

// Example_sortKeys demonstrates a technique for sorting a struct type using programmable sort criteria.
func main() {
	// Closures that order the Planet structure.
	name := func(p1, p2 *Planet) bool {
		return p1.name < p2.name
	}
	mass := func(p1, p2 *Planet) bool {
		return p1.mass < p2.mass
	}
	distance := func(p1, p2 *Planet) bool {
		return p1.distance < p2.distance
	}
	decreasingDistance := func(p1, p2 *Planet) bool {
		return distance(p2, p1)
	}

	// Sort the planets by the various criteria.
	By(name).Sort(planets)
	fmt.Println("By name:", planets)

	By(mass).Sort(planets)
	fmt.Println("By mass:", planets)

	By(distance).Sort(planets)
	fmt.Println("By distance:", planets)

	By(decreasingDistance).Sort(planets)
	fmt.Println("By decreasing distance:", planets)

}

Output:

By name: [{Earth 1 1} {Mars 0.107 1.5} {Mercury 0.055 0.4} {Venus 0.815 0.7}]
By mass: [{Mercury 0.055 0.4} {Mars 0.107 1.5} {Venus 0.815 0.7} {Earth 1 1}]
By distance: [{Mercury 0.055 0.4} {Venus 0.815 0.7} {Earth 1 1} {Mars 0.107 1.5}]
By decreasing distance: [{Mars 0.107 1.5} {Earth 1 1} {Venus 0.815 0.7} {Mercury 0.055 0.4}]
Example (SortMultiKeys)

Example_sortMultiKeys demonstrates a technique for sorting a struct type using different sets of multiple fields in the comparison. We chain together "Less" functions, each of which compares a single field.

package main

import (
	"fmt"
	"sort"
)

// A Change is a record of source code changes, recording user, language, and delta size.
type Change struct {
	user     string
	language string
	lines    int
}

type lessFunc func(p1, p2 *Change) bool

// multiSorter implements the Sort interface, sorting the changes within.
type multiSorter struct {
	changes []Change
	less    []lessFunc
}

// Sort sorts the argument slice according to the less functions passed to OrderedBy.
func (ms *multiSorter) Sort(changes []Change) {
	ms.changes = changes
	sort.Sort(ms)
}

// OrderedBy returns a Sorter that sorts using the less functions, in order.
// Call its Sort method to sort the data.
func OrderedBy(less ...lessFunc) *multiSorter {
	return &multiSorter{
		less: less,
	}
}

// Len is part of sort.Interface.
func (ms *multiSorter) Len() int {
	return len(ms.changes)
}

// Swap is part of sort.Interface.
func (ms *multiSorter) Swap(i, j int) {
	ms.changes[i], ms.changes[j] = ms.changes[j], ms.changes[i]
}

// Less is part of sort.Interface. It is implemented by looping along the
// less functions until it finds a comparison that discriminates between
// the two items (one is less than the other). Note that it can call the
// less functions twice per call. We could change the functions to return
// -1, 0, 1 and reduce the number of calls for greater efficiency: an
// exercise for the reader.
func (ms *multiSorter) Less(i, j int) bool {
	p, q := &ms.changes[i], &ms.changes[j]
	// Try all but the last comparison.
	var k int
	for k = 0; k < len(ms.less)-1; k++ {
		less := ms.less[k]
		switch {
		case less(p, q):
			// p < q, so we have a decision.
			return true
		case less(q, p):
			// p > q, so we have a decision.
			return false
		}
		// p == q; try the next comparison.
	}
	// All comparisons to here said "equal", so just return whatever
	// the final comparison reports.
	return ms.less[k](p, q)
}

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

// Example_sortMultiKeys demonstrates a technique for sorting a struct type using different
// sets of multiple fields in the comparison. We chain together "Less" functions, each of
// which compares a single field.
func main() {
	// Closures that order the Change structure.
	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 c1.lines > c2.lines // Note: > orders downwards.
	}

	// Simple use: Sort by user.
	OrderedBy(user).Sort(changes)
	fmt.Println("By user:", changes)

	// More examples.
	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)

}

Output:

By user: [{dmr C 100} {glenda Go 200} {gri Go 100} {gri Smalltalk 80} {ken C 150} {ken Go 200} {r Go 100} {r C 150} {rsc Go 200}]
By user,<lines: [{dmr C 100} {glenda Go 200} {gri Smalltalk 80} {gri Go 100} {ken C 150} {ken Go 200} {r Go 100} {r C 150} {rsc Go 200}]
By user,>lines: [{dmr C 100} {glenda Go 200} {gri Go 100} {gri Smalltalk 80} {ken Go 200} {ken C 150} {r C 150} {r Go 100} {rsc Go 200}]
By language,<lines: [{dmr C 100} {ken C 150} {r C 150} {gri Go 100} {r Go 100} {glenda Go 200} {ken Go 200} {rsc Go 200} {gri Smalltalk 80}]
By language,<lines,user: [{dmr C 100} {ken C 150} {r C 150} {gri Go 100} {r Go 100} {glenda Go 200} {ken Go 200} {rsc Go 200} {gri Smalltalk 80}]
Example (SortWrapper)
package main

import (
	"fmt"
	"sort"
)

type Grams int

func (g Grams) String() string { return fmt.Sprintf("%dg", int(g)) }

type Organ struct {
	Name   string
	Weight Grams
}

type Organs []*Organ

func (s Organs) Len() int      { return len(s) }
func (s Organs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

// ByName implements sort.Interface by providing Less and using the Len and
// Swap methods of the embedded Organs value.
type ByName struct{ Organs }

func (s ByName) Less(i, j int) bool { return s.Organs[i].Name < s.Organs[j].Name }

// ByWeight implements sort.Interface by providing Less and using the Len and
// Swap methods of the embedded Organs value.
type ByWeight struct{ Organs }

func (s ByWeight) Less(i, j int) bool { return s.Organs[i].Weight < s.Organs[j].Weight }

func main() {
	s := []*Organ{
		{"brain", 1340},
		{"heart", 290},
		{"liver", 1494},
		{"pancreas", 131},
		{"prostate", 62},
		{"spleen", 162},
	}

	sort.Sort(ByWeight{s})
	fmt.Println("Organs by weight:")
	printOrgans(s)

	sort.Sort(ByName{s})
	fmt.Println("Organs by name:")
	printOrgans(s)

}

func printOrgans(s []*Organ) {
	for _, o := range s {
		fmt.Printf("%-8s (%v)\n", o.Name, o.Weight)
	}
}

Output:

Organs by weight:
prostate (62g)
pancreas (131g)
spleen   (162g)
heart    (290g)
brain    (1340g)
liver    (1494g)
Organs by name:
brain    (1340g)
heart    (290g)
liver    (1494g)
pancreas (131g)
prostate (62g)
spleen   (162g)

Index

Examples

Functions

func Find

func Find(n int, cmp func(int) int) (i int, found bool)

Find 使用二分搜索查找并返回 [0, n) 中满足 cmp(i) <= 0 的最小索引 i。 如果没有这样的索引 i,Find 返回 i = n。 如果 i < n 且 cmp(i) == 0,则 found 结果为 true。 Find 仅对 [0, n) 范围内的 i 调用 cmp(i)。

为了允许二分搜索,Find 要求在范围的前导前缀中 cmp(i) > 0, 在中间 cmp(i) == 0,在最终后缀中 cmp(i) < 0。(每个子范围可以为空。) 建立此条件的常用方法是将 cmp(i) 解释为将所需目标值 t 与 底层索引数据结构 x 中的条目 i 进行比较, 当 t < x[i]、t == x[i] 和 t > x[i] 时分别返回 <0、0 和 >0。

例如,在已排序的随机访问字符串列表中查找特定字符串:

i, found := sort.Find(x.Len(), func(i int) int {
    return strings.Compare(target, x.At(i))
})
if found {
    fmt.Printf("found %s at entry %d\n", target, i)
} else {
    fmt.Printf("%s not found, would insert at %d", target, i)
}
Example

This example demonstrates finding a string in a list sorted in ascending order.

package main

import (
	"fmt"
	"sort"
	"strings"
)

func main() {
	a := []string{"apple", "banana", "lemon", "mango", "pear", "strawberry"}

	for _, x := range []string{"banana", "orange"} {
		i, found := sort.Find(len(a), func(i int) int {
			return strings.Compare(x, a[i])
		})
		if found {
			fmt.Printf("found %s at index %d\n", x, i)
		} else {
			fmt.Printf("%s not found, would insert at %d\n", x, i)
		}
	}

}

Output:

found banana at index 1
orange not found, would insert at 4

func Float64s

func Float64s(x []float64)

Float64s 按递增顺序对 float64 切片进行排序。 非数字(NaN)值排在其他值之前。

注意:从 Go 1.22 开始,此函数直接调用 slices.Sort

Example
package main

import (
	"fmt"
	"math"
	"sort"
)

func main() {
	s := []float64{5.2, -1.3, 0.7, -3.8, 2.6} // unsorted
	sort.Float64s(s)
	fmt.Println(s)

	s = []float64{math.Inf(1), math.NaN(), math.Inf(-1), 0.0} // unsorted
	sort.Float64s(s)
	fmt.Println(s)

}

Output:

[-3.8 -1.3 0.7 2.6 5.2]
[NaN -Inf 0 +Inf]

func Float64sAreSorted

func Float64sAreSorted(x []float64) bool

Float64sAreSorted 报告 float64 切片 x 是否按递增顺序排序, 非数字(NaN)值排在其他值之前。

注意:从 Go 1.22 开始,此函数直接调用 slices.IsSorted

Example
package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []float64{0.7, 1.3, 2.6, 3.8, 5.2} // sorted ascending
	fmt.Println(sort.Float64sAreSorted(s))

	s = []float64{5.2, 3.8, 2.6, 1.3, 0.7} // sorted descending
	fmt.Println(sort.Float64sAreSorted(s))

	s = []float64{5.2, 1.3, 0.7, 3.8, 2.6} // unsorted
	fmt.Println(sort.Float64sAreSorted(s))

}

Output:

true
false
false

func Ints

func Ints(x []int)

Ints 按递增顺序对 int 切片进行排序。

注意:从 Go 1.22 开始,此函数直接调用 slices.Sort

Example
package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []int{5, 2, 6, 3, 1, 4} // unsorted
	sort.Ints(s)
	fmt.Println(s)
}

Output:

[1 2 3 4 5 6]

func IntsAreSorted

func IntsAreSorted(x []int) bool

IntsAreSorted 报告 int 切片 x 是否按递增顺序排序。

注意:从 Go 1.22 开始,此函数直接调用 slices.IsSorted

Example
package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []int{1, 2, 3, 4, 5, 6} // sorted ascending
	fmt.Println(sort.IntsAreSorted(s))

	s = []int{6, 5, 4, 3, 2, 1} // sorted descending
	fmt.Println(sort.IntsAreSorted(s))

	s = []int{3, 2, 4, 1, 5} // unsorted
	fmt.Println(sort.IntsAreSorted(s))

}

Output:

true
false
false

func IsSorted

func IsSorted(data Interface) bool

IsSorted 报告数据是否已排序。

注意:在许多情况下,更新的 slices.IsSortedFunc 函数更加人性化且运行更快。

func Search(n int, f func(int) bool) int

Search 使用二分搜索查找并返回最小的索引 i, 位于 [0, n) 中且满足 f(i) 为 true,假设在范围 [0, n) 上, f(i) == true 意味着 f(i+1) == true。也就是说,Search 要求 f 对于输入范围 [0, n) 的某个(可能为空的)前缀为 false, 然后对(可能为空的)剩余部分为 true;Search 返回第一个 true 索引。 如果没有这样的索引,Search 返回 n。 (请注意,"未找到"的返回值不是 -1,例如 strings.Index 的情况。) Search 仅对 [0, n) 范围内的 i 调用 f(i)。

Search 的一个常见用途是在已排序的、可索引的数据结构(如数组或切片)中 查找值 x 的索引 i。在这种情况下,参数 f(通常是闭包)捕获要查找的值, 以及数据结构的索引和排序方式。

例如,给定一个按升序排序的切片 data, 调用 Search(len(data), func(i int) bool { return data[i] >= 23 }) 返回满足 data[i] >= 23 的最小索引 i。如果调用者想查找 23 是否在切片中, 必须单独测试 data[i] == 23。

搜索按降序排序的数据将使用 <= 运算符而不是 >= 运算符。

完整的示例中,以下代码尝试在按升序排序的整数切片 data 中查找值 x:

x := 23
i := sort.Search(len(data), func(i int) bool { return data[i] >= x })
if i < len(data) && data[i] == x {
	// x 存在于 data[i] 处
} else {
	// x 不存在于 data 中,
	// 但 i 是它将被插入的索引。
}

作为一个更幽默的例子,这个程序猜你的数字:

func GuessingGame() {
	var s string
	fmt.Printf("Pick an integer from 0 to 100.\n")
	answer := sort.Search(100, func(i int) bool {
		fmt.Printf("Is your number <= %d? ", i)
		fmt.Scanf("%s", &s)
		return s != "" && s[0] == 'y'
	})
	fmt.Printf("Your number is %d.\n", answer)
}
Example (DescendingOrder)

This example demonstrates searching a list sorted in descending order. The approach is the same as searching a list in ascending order, but with the condition inverted.

package main

import (
	"fmt"
	"sort"
)

func main() {
	a := []int{55, 45, 36, 28, 21, 15, 10, 6, 3, 1}
	x := 6

	i := sort.Search(len(a), func(i int) bool { return a[i] <= x })
	if i < len(a) && a[i] == x {
		fmt.Printf("found %d at index %d in %v\n", x, i, a)
	} else {
		fmt.Printf("%d not found in %v\n", x, a)
	}
}

Output:

found 6 at index 7 in [55 45 36 28 21 15 10 6 3 1]

func SearchFloat64s

func SearchFloat64s(a []float64, x float64) int

SearchFloat64s 在已排序的 float64 切片中搜索 x,并返回如 Search 所指定的索引。 如果 x 不存在,返回值是插入 x 的索引(可以是 len(a))。 切片必须按升序排序。

Example

This example demonstrates searching for float64 in a list sorted in ascending order.

package main

import (
	"fmt"
	"sort"
)

func main() {
	a := []float64{1.0, 2.0, 3.3, 4.6, 6.1, 7.2, 8.0}

	x := 2.0
	i := sort.SearchFloat64s(a, x)
	fmt.Printf("found %g at index %d in %v\n", x, i, a)

	x = 0.5
	i = sort.SearchFloat64s(a, x)
	fmt.Printf("%g not found, can be inserted at index %d in %v\n", x, i, a)
}

Output:

found 2 at index 1 in [1 2 3.3 4.6 6.1 7.2 8]
0.5 not found, can be inserted at index 0 in [1 2 3.3 4.6 6.1 7.2 8]

func SearchInts

func SearchInts(a []int, x int) int

SearchInts 在已排序的 int 切片中搜索 x,并返回如 Search 所指定的索引。 如果 x 不存在,返回值是插入 x 的索引(可以是 len(a))。 切片必须按升序排序。

Example

This example demonstrates searching for int in a list sorted in ascending order.

package main

import (
	"fmt"
	"sort"
)

func main() {
	a := []int{1, 2, 3, 4, 6, 7, 8}

	x := 2
	i := sort.SearchInts(a, x)
	fmt.Printf("found %d at index %d in %v\n", x, i, a)

	x = 5
	i = sort.SearchInts(a, x)
	fmt.Printf("%d not found, can be inserted at index %d in %v\n", x, i, a)
}

Output:

found 2 at index 1 in [1 2 3 4 6 7 8]
5 not found, can be inserted at index 4 in [1 2 3 4 6 7 8]

func SearchStrings

func SearchStrings(a []string, x string) int

SearchStrings 在已排序的 string 切片中搜索 x,并返回如 Search 所指定的索引。 如果 x 不存在,返回值是插入 x 的索引(可以是 len(a))。 切片必须按升序排序。

Example

This example demonstrates searching for string in a list sorted in ascending order.

package main

import (
	"fmt"
	"sort"
)

func main() {
	a := []string{"apple", "banana", "cherry", "date", "fig", "grape"}

	x := "banana"
	i := sort.SearchStrings(a, x)
	fmt.Printf("found %s at index %d in %v\n", x, i, a)

	x = "coconut"
	i = sort.SearchStrings(a, x)
	fmt.Printf("%s not found, can be inserted at index %d in %v\n", x, i, a)

}

Output:

found banana at index 1 in [apple banana cherry date fig grape]
coconut not found, can be inserted at index 3 in [apple banana cherry date fig grape]

func Slice

func Slice(x any, less func(i, j int) bool)

Slice 使用提供的 less 函数对切片 x 进行排序。 如果 x 不是切片,它会 panic。

不保证排序是稳定的:相等的元素可能与其原始顺序相反。 要进行稳定排序,请使用 SliceStable

less 函数必须满足与 Interface 类型的 Less 方法相同的要求。

注意:在许多情况下,更新的 slices.SortFunc 函数更加人性化且运行更快。

Example
package main

import (
	"fmt"
	"sort"
)

func main() {
	people := []struct {
		Name string
		Age  int
	}{
		{"Gopher", 7},
		{"Alice", 55},
		{"Vera", 24},
		{"Bob", 75},
	}
	sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
	fmt.Println("By name:", people)

	sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age })
	fmt.Println("By age:", people)
}

Output:

By name: [{Alice 55} {Bob 75} {Gopher 7} {Vera 24}]
By age: [{Gopher 7} {Vera 24} {Alice 55} {Bob 75}]

func SliceIsSorted

func SliceIsSorted(x any, less func(i, j int) bool) bool

SliceIsSorted 报告切片 x 是否根据提供的 less 函数排序。 如果 x 不是切片,它会 panic。

注意:在许多情况下,更新的 slices.IsSortedFunc 函数更加人性化且运行更快。

Example
package main

import (
	"fmt"
	"sort"
)

func main() {
	numbers := []int{1, 2, 3, 4, 5, 6}

	isSortedAsc := sort.SliceIsSorted(numbers, func(i, j int) bool {
		return numbers[i] < numbers[j]
	})
	fmt.Printf("%v sorted ascending: %t\n", numbers, isSortedAsc)

	numbersDesc := []int{6, 5, 4, 3, 2, 1}

	isSortedDesc := sort.SliceIsSorted(numbersDesc, func(i, j int) bool {
		return numbersDesc[i] > numbersDesc[j]
	})
	fmt.Printf("%v sorted descending: %t\n", numbers, isSortedDesc)

	unsortedNumbers := []int{1, 3, 2, 4, 5}

	isSortedUnsorted := sort.SliceIsSorted(unsortedNumbers, func(i, j int) bool {
		return unsortedNumbers[i] < unsortedNumbers[j]
	})
	fmt.Printf("%v unsorted slice sorted: %t\n", unsortedNumbers, isSortedUnsorted)

}

Output:

[1 2 3 4 5 6] sorted ascending: true
[1 2 3 4 5 6] sorted descending: true
[1 3 2 4 5] unsorted slice sorted: false

func SliceStable

func SliceStable(x any, less func(i, j int) bool)

SliceStable 使用提供的 less 函数对切片 x 进行排序, 保持相等元素在其原始顺序中。 如果 x 不是切片,它会 panic。

less 函数必须满足与 Interface 类型的 Less 方法相同的要求。

注意:在许多情况下,更新的 slices.SortStableFunc 函数更加人性化且运行更快。

Example
package main

import (
	"fmt"
	"sort"
)

func main() {

	people := []struct {
		Name string
		Age  int
	}{
		{"Alice", 25},
		{"Elizabeth", 75},
		{"Alice", 75},
		{"Bob", 75},
		{"Alice", 75},
		{"Bob", 25},
		{"Colin", 25},
		{"Elizabeth", 25},
	}

	// Sort by name, preserving original order
	sort.SliceStable(people, func(i, j int) bool { return people[i].Name < people[j].Name })
	fmt.Println("By name:", people)

	// Sort by age preserving name order
	sort.SliceStable(people, func(i, j int) bool { return people[i].Age < people[j].Age })
	fmt.Println("By age,name:", people)

}

Output:

By name: [{Alice 25} {Alice 75} {Alice 75} {Bob 75} {Bob 25} {Colin 25} {Elizabeth 75} {Elizabeth 25}]
By age,name: [{Alice 25} {Bob 25} {Colin 25} {Elizabeth 25} {Alice 75} {Alice 75} {Bob 75} {Elizabeth 75}]

func Sort

func Sort(data Interface)

Sort 根据 Less 方法确定的方式以升序排序数据。 它调用一次 data.Len 以确定 n,调用 O(n*log(n)) 次 data.Less 和 data.Swap。不保证排序是稳定的。

注意:在许多情况下,更新的 slices.SortFunc 函数更加人性化且运行更快。

func Stable

func Stable(data Interface)

Stable 根据 Less 方法以升序排序数据, 同时保持相等元素的原始顺序。

它调用一次 data.Len 以确定 n,调用 O(n*log(n)) 次 data.Less 和 O(n*log(n)*log(n)) 次 data.Swap。

注意:在许多情况下,更新的 slices.SortStableFunc 函数更加人性化且运行更快。

func Strings

func Strings(x []string)

Strings 按递增顺序对 string 切片进行排序。

注意:从 Go 1.22 开始,此函数直接调用 slices.Sort

Example
package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []string{"Go", "Bravo", "Gopher", "Alpha", "Grin", "Delta"}
	sort.Strings(s)
	fmt.Println(s)
}

Output:

[Alpha Bravo Delta Go Gopher Grin]

func StringsAreSorted

func StringsAreSorted(x []string) bool

StringsAreSorted 报告 string 切片 x 是否按递增顺序排序。

注意:从 Go 1.22 开始,此函数直接调用 slices.IsSorted

Types

type Float64Slice

type Float64Slice []float64

Float64Slice 实现 []float64 的 Interface,按递增顺序排序, 非数字(NaN)值排在其他值之前。

func (Float64Slice) Len

func (x Float64Slice) Len() int

func (Float64Slice) Less

func (x Float64Slice) Less(i, j int) bool

Less 报告 x[i] 是否应排在 x[j] 之前,这是 sort Interface 所要求的。 注意,浮点数比较本身不是传递关系:它不能为非数字(NaN)值报告一致的排序。 这个 Less 的实现通过以下方式将 NaN 值放在其他值之前:

x[i] < x[j] || (math.IsNaN(x[i]) && !math.IsNaN(x[j]))

func (Float64Slice) Search

func (p Float64Slice) Search(x float64) int

Search 返回将 SearchFloat64s 应用于接收者和 x 的结果。

func (Float64Slice) Sort

func (x Float64Slice) Sort()

Sort 是一个便捷方法:x.Sort() 调用 Sort(x)。

func (Float64Slice) Swap

func (x Float64Slice) Swap(i, j int)

type IntSlice

type IntSlice []int

IntSlice 将 Interface 的方法附加到 []int,按递增顺序排序。

func (IntSlice) Len

func (x IntSlice) Len() int

func (IntSlice) Less

func (x IntSlice) Less(i, j int) bool

func (IntSlice) Search

func (p IntSlice) Search(x int) int

Search 返回将 SearchInts 应用于接收者和 x 的结果。

func (IntSlice) Sort

func (x IntSlice) Sort()

Sort 是一个便捷方法:x.Sort() 调用 Sort(x)。

func (IntSlice) Swap

func (x IntSlice) Swap(i, j int)

type Interface

type Interface interface {
	// Len 是集合中元素的数量。
	Len() int

	// Less 报告索引为 i 的元素是否必须排在索引为 j 的元素之前。
	//
	// 如果 Less(i, j) 和 Less(j, i) 都为 false,
	// 则认为索引 i 和 j 处的元素相等。
	// Sort 可以在最终结果中以任意顺序放置相等的元素,
	// 而 Stable 会保留相等元素的原始输入顺序。
	//
	// Less 必须描述一个 [严格弱序]。例如:
	//  - 如果 Less(i, j) 和 Less(j, k) 都为 true,则 Less(i, k) 也必须为 true。
	//  - 如果 Less(i, j) 和 Less(j, k) 都为 false,则 Less(i, k) 也必须为 false。
	//
	// 注意,当涉及非数字(NaN)值时,浮点数的比较(float32 或 float64 值上的 < 运算符)
	// 不是严格弱序。
	// 有关浮点值的正确实现,请参见 Float64Slice.Less。
	//
	// [Strict Weak Ordering]: https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings
	Less(i, j int) bool

	// Swap 交换索引为 i 和 j 的元素。
	Swap(i, j int)
}

Interface 的实现可以被本包中的例程排序。 这些方法通过整数索引引用底层集合中的元素。

func Reverse

func Reverse(data Interface) Interface

Reverse 返回数据反序后的顺序。

Example
package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []int{5, 2, 6, 3, 1, 4} // unsorted
	sort.Sort(sort.Reverse(sort.IntSlice(s)))
	fmt.Println(s)
}

Output:

[6 5 4 3 2 1]

type StringSlice

type StringSlice []string

StringSlice 将 Interface 的方法附加到 []string,按递增顺序排序。

func (StringSlice) Len

func (x StringSlice) Len() int

func (StringSlice) Less

func (x StringSlice) Less(i, j int) bool

func (StringSlice) Search

func (p StringSlice) Search(x string) int

Search 返回将 SearchStrings 应用于接收者和 x 的结果。

func (StringSlice) Sort

func (x StringSlice) Sort()

Sort 是一个便捷方法:x.Sort() 调用 Sort(x)。

func (StringSlice) Swap

func (x StringSlice) Swap(i, j int)