Golang slices.IsSorted
最后修改于 2025 年 4 月 20 日
本教程将介绍如何在 Go 中使用 slices.IsSorted 函数。我们将通过检查排序顺序的实际示例来涵盖切片操作。
slices.IsSorted 函数用于测试切片是否按升序排序。它是 Go 实验性 slices 包的一部分。
此函数对于在执行需要排序输入的预操作之前,验证数据完整性或检查先决条件非常有用。
基本 slices.IsSorted 示例
slices.IsSorted 最简单的用法是检查整数切片是否按升序排序。该函数返回一个布尔结果。
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{1, 2, 3, 4, 5}
unsorted := []int{5, 3, 1, 4, 2}
fmt.Println("Numbers sorted:", slices.IsSorted(numbers))
fmt.Println("Unsorted sorted:", slices.IsSorted(unsorted))
}
我们创建了两个切片——一个已排序和一个未排序的。该函数通过比较相邻元素来正确识别它们的排序状态。
检查字符串切片
slices.IsSorted 使用字典顺序处理字符串切片。此示例演示了对字符串元素进行的排序检查。
package main
import (
"fmt"
"slices"
)
func main() {
words := []string{"apple", "banana", "cherry"}
mixed := []string{"zebra", "apple", "banana"}
fmt.Println("Words sorted:", slices.IsSorted(words))
fmt.Println("Mixed sorted:", slices.IsSorted(mixed))
}
字符串使用其 Unicode 码点进行比较。第一个切片顺序正确,而第二个切片未通过排序检查。
使用自定义类型
对于自定义类型,我们必须实现 cmp.Ordered 接口。此示例展示了如何检查结构体切片的排序。
package main
import (
"cmp"
"fmt"
"slices"
)
type Person struct {
Name string
Age int
}
func main() {
people := []Person{
{"Alice", 25},
{"Bob", 30},
{"Charlie", 35},
}
unsortedPeople := []Person{
{"Charlie", 35},
{"Alice", 25},
{"Bob", 30},
}
fmt.Println("People sorted by age:",
slices.IsSortedFunc(people, func(a, b Person) int {
return cmp.Compare(a.Age, b.Age)
}))
fmt.Println("Unsorted people:",
slices.IsSortedFunc(unsortedPeople, func(a, b Person) int {
return cmp.Compare(a.Age, b.Age)
}))
}
我们使用 slices.IsSortedFunc 和自定义比较函数。该函数检查元素是否按年龄升序排序。
空切片和单元素切片
slices.IsSorted 对于空切片和单元素切片有特殊的行为。根据定义,这两种情况都被认为是已排序的。
package main
import (
"fmt"
"slices"
)
func main() {
empty := []int{}
single := []string{"hello"}
fmt.Println("Empty slice sorted:", slices.IsSorted(empty))
fmt.Println("Single-element sorted:", slices.IsSorted(single))
}
对于这些边缘情况,该函数返回 true,因为没有元素违反排序顺序。这符合排序的数学定义。
降序检查
要检查降序,我们可以使用 slices.IsSortedFunc 和反向比较。此示例演示了该技术。
package main
import (
"cmp"
"fmt"
"slices"
)
func main() {
descending := []int{5, 4, 3, 2, 1}
ascending := []int{1, 2, 3, 4, 5}
isDescending := slices.IsSortedFunc(descending, func(a, b int) int {
return cmp.Compare(b, a) // Reverse comparison
})
fmt.Println("Descending sorted:", isDescending)
fmt.Println("Ascending as descending:",
slices.IsSortedFunc(ascending, func(a, b int) int {
return cmp.Compare(b, a)
}))
}
通过比较 b 和 a,而不是 a 和 b,我们有效地检查了降序。第一个切片通过了检查,而第二个切片未通过。
性能注意事项
对于大型切片,slices.IsSorted 非常高效,因为它会在第一个无序元素处停止。此示例演示了其提前终止。
package main
import (
"fmt"
"slices"
"time"
)
func main() {
// Large mostly-sorted slice with one unsorted element at start
largeSlice := make([]int, 1_000_000)
for i := range largeSlice {
largeSlice[i] = i
}
largeSlice[0] = 1_000_000 // Make first element out of order
start := time.Now()
sorted := slices.IsSorted(largeSlice)
elapsed := time.Since(start)
fmt.Printf("Checked 1M elements in %v\n", elapsed)
fmt.Println("Slice sorted:", sorted)
}
该函数很快返回,因为它立即找到了无序的元素。这使其对于验证可能未排序的数据非常高效。
实际示例:输入验证
这个实际示例使用 slices.IsSorted 来验证用户输入的数字是否按升序提供。
package main
import (
"fmt"
"slices"
"strconv"
)
func main() {
inputs := []string{"10", "20", "30", "15"}
numbers := make([]int, len(inputs))
for i, s := range inputs {
num, err := strconv.Atoi(s)
if err != nil {
fmt.Println("Invalid input:", s)
return
}
numbers[i] = num
}
if slices.IsSorted(numbers) {
fmt.Println("Inputs are in ascending order")
} else {
fmt.Println("Inputs are not properly sorted")
}
}
我们将字符串转换为整数并验证它们已排序。这展示了应用程序中数据验证的实际用例。
来源
本教程通过各种场景下的排序检查实际示例,介绍了 Go 中的 slices.IsSorted 函数。