Golang slices.Sorted
最后修改于 2025 年 4 月 20 日
本教程解释了如何在 Go 中使用 slices.Sorted 函数。我们将通过实际示例介绍切片操作,并检查排序顺序。
slices.Sorted 函数用于测试切片是否按升序排序。它是 Go 实验性 slices 包的一部分。
此函数对于验证数据或在执行需要已排序输入的 যেসব操作之前检查先决条件非常有用。它返回一个布尔值。
基本 slices.Sorted 示例
slices.Sorted 最简单的用法是检查整数切片是否按升序排序。该函数不需要额外的参数。
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.Sorted(numbers))
fmt.Println("Unsorted sorted:", slices.Sorted(unsorted))
}
我们创建了两个切片——一个已排序和一个未排序的。该函数能正确识别它们的排序状态。输出分别显示 true 和 false。
检查字符串切片
slices.Sorted 也适用于字符串切片。此示例检查单词切片是否按字母顺序排列。
package main
import (
"fmt"
"slices"
)
func main() {
words := []string{"apple", "banana", "cherry"}
mixed := []string{"zebra", "apple", "banana"}
fmt.Println("Words sorted:", slices.Sorted(words))
fmt.Println("Mixed sorted:", slices.Sorted(mixed))
}
该函数对字符串使用字典序。第一个切片顺序正确,而第二个切片不正确,因为“zebra”排在“apple”之前。
使用自定义类型
对于自定义类型,我们需要实现 Ordered 接口。此示例演示了如何检查自定义结构切片的排序。
package main
import (
"fmt"
"slices"
)
type Person struct {
Name string
Age int
}
func main() {
people := []Person{
{"Alice", 25},
{"Bob", 30},
{"Charlie", 35},
}
unsortedPeople := []Person{
{"Bob", 30},
{"Alice", 25},
{"Charlie", 35},
}
fmt.Println("People sorted:", slices.SortedFunc(people, func(a, b Person) int {
return a.Age - b.Age
}))
fmt.Println("Unsorted people:", slices.SortedFunc(unsortedPeople, func(a, b Person) int {
return a.Age - b.Age
}))
}
注意:这里我们使用 SortedFunc,因为 Sorted 需要 Ordered 约束。比较函数根据年龄定义我们的排序顺序。
空切片和单元素切片
slices.Sorted 对边缘情况有特殊的行为。空切片和单元素切片始终被视为已排序。
package main
import (
"fmt"
"slices"
)
func main() {
empty := []int{}
single := []string{"alone"}
fmt.Println("Empty sorted:", slices.Sorted(empty))
fmt.Println("Single element sorted:", slices.Sorted(single))
}
这些情况返回 true,因为没有要比较的元素,或者只有一个元素。这符合已排序的数学定义。
检查降序
要检查降序,我们可以使用带有自定义比较的 slices.SortedFunc。此示例演示了两个方向。
package main
import (
"fmt"
"slices"
)
func main() {
asc := []int{1, 2, 3, 4, 5}
desc := []int{5, 4, 3, 2, 1}
fmt.Println("Ascending sorted:", slices.Sorted(asc))
fmt.Println("Descending sorted:", slices.IsSortedFunc(desc, func(a, b int) int {
return b - a // Reverse comparison
}))
}
标准的 Sorted 只检查升序。对于降序,我们提供一个反转常规顺序的比较函数。
性能注意事项
对于大型切片,slices.Sorted 的性能很重要。此示例在不同切片大小上对该操作进行了基准测试。
package main
import (
"fmt"
"slices"
"time"
)
func main() {
sizes := []int{1_000, 10_000, 100_000}
for _, size := range sizes {
slice := make([]int, size)
for i := range slice {
slice[i] = i
}
start := time.Now()
_ = slices.Sorted(slice)
fmt.Printf("Size %d: %v\n", size, time.Since(start))
}
}
该函数在找到第一个无序元素时停止。如果前两个元素无序,则最佳情况性能为 O(1)。
实际示例:输入验证
这个实际示例验证了用户提供的数字在处理前已排序。它演示了实际用法。
package main
import (
"fmt"
"slices"
"strconv"
)
func main() {
inputs := []string{"10", "20", "15", "30"}
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.Sorted(numbers) {
fmt.Println("Processing sorted numbers...")
// Perform operations that require sorted input
} else {
fmt.Println("Error: Numbers must be provided in sorted order")
}
}
我们将字符串转换为整数,然后验证它们是否已排序。这种模式在处理需要排序以确保正确性的数据时很常见。
来源
本教程通过实际示例介绍了 Go 中的 slices.Sorted 函数,涵盖了各种场景和数据类型的排序检查。