Golang slices.IsSortedFunc
最后修改于 2025 年 4 月 20 日
本教程将解释如何在 Go 中使用 slices.IsSortedFunc
函数。我们将通过实际示例来讲解切片操作以及如何检查排序顺序。
slices.IsSortedFunc
函数用于根据自定义比较函数测试切片是否已排序。它是 Go 实验性 slices 包的一部分。
此函数可用于验证除简单的升序或降序序列之外的自定义排序顺序。如果切片按定义排序,则返回 true。
基本的 slices.IsSortedFunc 示例
slices.IsSortedFunc
最简单的用法是检查数字是否按升序排序。我们定义一个返回 -1、0 或 1 的比较函数。
package main import ( "cmp" "fmt" "slices" ) func main() { numbers := []int{1, 2, 3, 4, 5} isSorted := slices.IsSortedFunc(numbers, func(a, b int) int { return cmp.Compare(a, b) }) fmt.Println("Is sorted:", isSorted) }
我们创建一个已排序的切片,并使用标准比较检查其顺序。由于数字是升序排列的,因此函数返回 true。
检查降序
slices.IsSortedFunc
可通过反转比较逻辑来验证降序。此示例检查数字是否按从高到低的顺序排序。
package main import ( "cmp" "fmt" "slices" ) func main() { numbers := []int{5, 4, 3, 2, 1} isSorted := slices.IsSortedFunc(numbers, func(a, b int) int { return cmp.Compare(b, a) // Reverse comparison }) fmt.Println("Is sorted descending:", isSorted) }
通过将 b 与 a 进行比较而不是将 a 与 b 进行比较,我们反转了排序顺序检查。该函数确认我们的切片已正确按降序排序。
自定义结构排序
我们可以将 slices.IsSortedFunc
与自定义结构类型一起使用。此示例检查人员是否按年龄排序。
package main import ( "cmp" "fmt" "slices" ) type Person struct { Name string Age int } func main() { people := []Person{ {"Alice", 25}, {"Bob", 30}, {"Charlie", 35}, } isSorted := slices.IsSortedFunc(people, func(a, b Person) int { return cmp.Compare(a.Age, b.Age) }) fmt.Println("Sorted by age:", isSorted) }
比较函数会检查每个 Person 结构的 Age 字段。由于年龄是顺序增加的,因此函数返回 true。
不区分大小写的字符串排序
slices.IsSortedFunc
可以处理不区分大小写的字符串比较。此示例检查单词是否按字母顺序排序,忽略大小写。
package main import ( "fmt" "slices" "strings" ) func main() { words := []string{"apple", "Banana", "cherry"} isSorted := slices.IsSortedFunc(words, func(a, b string) int { return strings.Compare(strings.ToLower(a), strings.ToLower(b)) }) fmt.Println("Case-insensitive sorted:", isSorted) }
我们在比较之前将字符串转换为小写,以忽略大小写差异。该函数会确认我们的切片是否按字母顺序排列,而不管大小写。
空切片和单元素切片
slices.IsSortedFunc
对空切片和单元素切片有特殊行为。这些情况始终被视为已排序。
package main import ( "fmt" "slices" ) func main() { empty := []int{} single := []string{"hello"} emptySorted := slices.IsSortedFunc(empty, func(a, b int) int { return 0 // Doesn't matter }) singleSorted := slices.IsSortedFunc(single, func(a, b string) int { return 0 // Doesn't matter }) fmt.Println("Empty sorted:", emptySorted) fmt.Println("Single-element sorted:", singleSorted) }
当元素为零或一个时,没有需要比较的对。根据定义,这些情况下函数返回 true。
复杂的自定义排序
我们可以使用 slices.IsSortedFunc
实现复杂的排序逻辑。此示例检查点是否按与原点的距离排序。
package main import ( "fmt" "math" "slices" ) type Point struct { X, Y float64 } func main() { points := []Point{ {1, 1}, {2, 2}, {3, 3}, } isSorted := slices.IsSortedFunc(points, func(a, b Point) int { distA := math.Sqrt(a.X*a.X + a.Y*a.Y) distB := math.Sqrt(b.X*b.X + b.Y*b.Y) if distA < distB { return -1 } else if distA > distB { return 1 } return 0 }) fmt.Println("Sorted by distance:", isSorted) }
我们在比较之前计算每个点与原点的距离。该函数验证点是否按距离递增排序。
实际示例:版本号
这个实际示例检查版本字符串是否排序正确,并适当处理带有点的数字格式。
package main import ( "fmt" "slices" "strconv" "strings" ) func main() { versions := []string{"1.2", "1.10", "1.9", "2.0"} isSorted := slices.IsSortedFunc(versions, func(a, b string) int { aParts := strings.Split(a, ".") bParts := strings.Split(b, ".") for i := 0; i < len(aParts) && i < len(bParts); i++ { aNum, _ := strconv.Atoi(aParts[i]) bNum, _ := strconv.Atoi(bParts[i]) if aNum != bNum { return aNum - bNum } } return len(aParts) - len(bParts) }) fmt.Println("Versions sorted correctly:", isSorted) }
我们将版本字符串拆分为组件并进行数字比较。由于“1.10”应排在“1.9”之后,因此函数返回 false。
来源
本教程通过实际示例涵盖了 Go 中的 slices.IsSortedFunc
函数,演示了如何在各种场景下检查自定义排序顺序。