【go语言系列学习】01.接口-实例:对结构体切片按照自定义要求排序

接口 实例

对结构体切片进行排序

func Sort(data Interface)


Sort sorts data in ascending order as determined by the Less method. It makes one call to data.Len to determine n and O(n*log(n)) calls to data.Less and data.Swap. The sort is not guaranteed to be stable.

/*
源码可参考:https://cs.opensource.google/go/go/+/refs/tags/go1.19.2:src/sort/sort.go;l=42
https://pkg.go.dev/sort#Sort
*/

Interface接口的定义如下:

type Interface interface {
	// Len is the number of elements in the collection.
	Len() int

	// Less reports whether the element with index i
	// must sort before the element with index j.
	//
	// If both Less(i, j) and Less(j, i) are false,
	// then the elements at index i and j are considered equal.
	// Sort may place equal elements in any order in the final result,
	// while Stable preserves the original input order of equal elements.
	//
	// Less must describe a transitive ordering:
	//  - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well.
	//  - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well.
	//
	// Note that floating-point comparison (the < operator on float32 or float64 values)
	// is not a transitive ordering when not-a-number (NaN) values are involved.
	// See Float64Slice.Less for a correct implementation for floating-point values.
	Less(i, j int) bool

	// Swap swaps the elements with indexes i and j.
	Swap(i, j int)
}

所以,只要实现了Interface接口的类型,就可以调用Sort方法进行排序

package main

import (
	"fmt"
	"math/rand"
	"sort"
)

// 1.声明Hero结构体
type Hero struct {
	Name string
	Age  int
}

// 2.声明Hero结构体切片类型
type HeroSlice []Hero

// 3.实现Interface接口 有三个方法: Len Less Swap
func (hs HeroSlice) Len() int {
	return len(hs)
}

// 该方法决定使用什么标准排序,可以按照自己的要求书写
func (hs HeroSlice) Less(i, j int) bool {
	return hs[i].Age < hs[j].Age
}

func (hs HeroSlice) Swap(i, j int) {
	// 实现方式1
	// temp := hs[i]
	// hs[i] = hs[j]
	// hs[j] = temp

	// 实现方式2
	hs[i], hs[j] = hs[j], hs[i]
}

func main() {
	// 1. 定义数组切片,对数组切片进行排序
	var intSlice = []int{0, -1, 10, 7, 90}
	fmt.Println(intSlice)

	sort.Ints(intSlice) // 切片是引用类型
	fmt.Println(intSlice)

	// 2. 定义结构体切片,对结构体切片进行排序
	var heroSlices HeroSlice
	for i := 0; i < 10; i++ {
		hero := Hero{
			Name: fmt.Sprintf("英雄*%d", rand.Intn(100)),
			Age:  rand.Intn(100),
		}
		heroSlices = append(heroSlices, hero)
	}
	fmt.Println("===结构体切片 排序前===")
	for _, hero := range heroSlices {
		fmt.Println(hero)
	}

	sort.Sort(heroSlices)
	fmt.Println("===结构体切片 排序后===")
	for _, hero := range heroSlices {
		fmt.Println(hero)
	}

}

/*
[0 -1 10 7 90]
[-1 0 7 10 90]
===结构体切片 排序前===
{英雄*81 87}
{英雄*47 59}
{英雄*81 18}
{英雄*25 40}
{英雄*56 0}
{英雄*94 11}
{英雄*62 89}
{英雄*28 74}
{英雄*11 45}
{英雄*37 6}
===结构体切片 排序后===
{英雄*56 0}
{英雄*37 6}
{英雄*94 11}
{英雄*81 18}
{英雄*25 40}
{英雄*11 45}
{英雄*47 59}
{英雄*28 74}
{英雄*81 87}
{英雄*62 89}
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安安csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值