Golang中切片排序的实现方法

Golang中切片排序的实现方法 有没有办法对切片进行排序并将其赋值给另一个变量?我注意到 sort.Ints() 方法会改变原始切片。

func main() {
	xi := []int{4, 7, 3, 42, 99, 18, 16, 56, 12}
	fmt.Println(xi)
	sort.Ints(xi)
	fmt.Println(xi)


}

我尝试了这些方法: newXi := sort.Ints(xi)

var newXi1 int[]
newXi1 = sort.Ints(xi)
var newXi2 int[]
append(newXi2, sort.Ints(xi))

但它们都不起作用。有什么建议吗?


更多关于Golang中切片排序的实现方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

复制切片,然后对副本进行排序

更多关于Golang中切片排序的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


哈哈,我怎么没想到这一点……我真惭愧。谢谢老兄!

在Go语言中,sort.Ints() 函数确实会原地排序并修改原始切片。如果你需要保留原始切片,同时获得一个排序后的副本,可以这样做:

package main

import (
	"fmt"
	"sort"
)

func main() {
	xi := []int{4, 7, 3, 42, 99, 18, 16, 56, 12}
	
	// 方法1:先复制再排序
	newXi := make([]int, len(xi))
	copy(newXi, xi)
	sort.Ints(newXi)
	
	fmt.Println("原始切片:", xi)      // [4 7 3 42 99 18 16 56 12]
	fmt.Println("排序后副本:", newXi)  // [3 4 7 12 16 18 42 56 99]
	
	// 方法2:使用 append 复制
	newXi2 := append([]int{}, xi...)
	sort.Ints(newXi2)
	
	fmt.Println("原始切片:", xi)       // 保持不变
	fmt.Println("append副本:", newXi2) // 排序后的副本
	
	// 方法3:通用函数(支持任意类型)
	newXi3 := sortAndCopy(xi)
	fmt.Println("函数副本:", newXi3)
}

// 通用排序复制函数
func sortAndCopy[T constraints.Ordered](slice []T) []T {
	copied := make([]T, len(slice))
	copy(copied, slice)
	sort.Slice(copied, func(i, j int) bool {
		return copied[i] < copied[j]
	})
	return copied
}

对于其他类型的切片,可以使用 sort.Slice()

func main() {
	// 字符串切片
	xs := []string{"banana", "apple", "cherry"}
	sortedStrings := make([]string, len(xs))
	copy(sortedStrings, xs)
	sort.Strings(sortedStrings)
	
	fmt.Println("原始:", xs)            // [banana apple cherry]
	fmt.Println("排序后:", sortedStrings) // [apple banana cherry]
	
	// 自定义结构体切片
	type Person struct {
		Name string
		Age  int
	}
	
	people := []Person{
		{"Alice", 30},
		{"Bob", 25},
		{"Charlie", 35},
	}
	
	sortedPeople := make([]Person, len(people))
	copy(sortedPeople, people)
	sort.Slice(sortedPeople, func(i, j int) bool {
		return sortedPeople[i].Age < sortedPeople[j].Age
	})
	
	fmt.Println("按年龄排序:", sortedPeople) // [{Bob 25} {Alice 30} {Charlie 35}]
}

如果你使用的是Go 1.21+,可以使用泛型函数:

import (
	"fmt"
	"slices"
)

func main() {
	xi := []int{4, 7, 3, 42, 99, 18, 16, 56, 12}
	
	// 使用 slices 包(Go 1.21+)
	newXi := slices.Clone(xi)
	slices.Sort(newXi)
	
	fmt.Println("原始:", xi)     // [4 7 3 42 99 18 16 56 12]
	fmt.Println("排序:", newXi)  // [3 4 7 12 16 18 42 56 99]
}

关键点是:先创建切片的副本,然后对副本进行排序。copy() 函数或 slices.Clone() 可以创建独立的内存副本,这样对副本的排序就不会影响原始切片。

回到顶部