golang中按照结构体的某个字段排序实例代码

目录
  • 概述
  • 从大到小排序
  • 按照结构体的某个字段排序
  • 使用 sort.Stable 进行稳定排序
  • 附:根据结构体中任意字段进行排序
  • 总结

概述

golang的sort包默认支持int, float64, string的从小大到排序:

int -> Ints(x []int)
float64 -> Float64s(x []float64)
string -> Strings(x []string)

同时它还提供了自定义的排序接口Interface,此接口保护三个方法。

type Interface interface {
    // Len is the number of elements in the collection.
    Len() int
    // Less reports whether the element with
    // index i should sort before the element with index j.
    Less(i, j int) bool
    // Swap swaps the elements with indexes i and j.
    Swap(i, j int)
}

golang默认提供了三个类型,他们都实现了Interface:
Float64Slice
IntSlice
StringSlice

从大到小排序

方法1:先使用提供的从大到小排序,再翻转

arr := []float64{0.1, 0.5, 0.8, 0.4, 0.2}

sort.Sort(sort.Reverse(sort.Float64Slice(arr)))
fmt.Println(arr) // [0.8 0.5 0.4 0.2 0.1]

方法二:自定义类型实现

type Float64SliceDecrement []float64
func (s Float64SliceDecrement) Len() int { return len(s) }
func (s Float64SliceDecrement) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s Float64SliceDecrement) Less(i, j int) bool { return s[i] > s[j] }
func main() {
	arr := []float64{0.1, 0.5, 0.8, 0.4, 0.2}

	sort.Sort(Float64SliceDecrement(arr))
	fmt.Println(arr) // [0.8 0.5 0.4 0.2 0.1]
}

按照结构体的某个字段排序

按年纪从大到小排序

type Persons struct {
	Age int
	Height int
}

type PersonsSliceDecrement []Persons
func (s PersonsSliceDecrement) Len() int { return len(s) }
func (s PersonsSliceDecrement) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s PersonsSliceDecrement) Less(i, j int) bool { return s[i].Age > s[j].Age }
func main() {
	arr1 := []Persons{
		Persons{10, 12},
		Persons{20, 12},
		Persons{9, 12},
		Persons{10, 12},
		Persons{11, 12},
	}
	sort.Sort(PersonsSliceDecrement(arr1))
	fmt.Println(arr1)
}

打印

[{20 12} {11 12} {10 12} {10 12} {9 12}]

按年纪从大到小,如果年纪相等的,按身高从小到到

type Persons struct {
	Age int
	Height int
}

type PersonsSliceDecrement []Persons
func (s PersonsSliceDecrement) Len() int { return len(s) }
func (s PersonsSliceDecrement) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s PersonsSliceDecrement) Less(i, j int) bool {
	if s[i].Age > s[j].Age {
		return true
	}
	if s[i].Age == s[j].Age && s[i].Height < s[j].Height {
		return true
	}
	return false
}

func main() {
	arr1 := []Persons{
		Persons{10, 120},
		Persons{20, 12},
		Persons{10, 110},
		Persons{10, 11},
		Persons{10, 100},
	}
	sort.Sort(PersonsSliceDecrement(arr1))
	fmt.Println(arr1)
}

打印

[{20 12} {10 11} {10 100} {10 110} {10 120}]

使用 sort.Stable 进行稳定排序

sort.Sort 并不保证排序的稳定性。如果有需要, 可以使用 sort.Stable ,用法就是将sort.Sort 替换为 sort.Stable

附:go根据结构体中任意字段进行排序

附:根据结构体中任意字段进行排序

Sort()

Reverse()

Less(i,j int) bool

Len() int

Swap(i,j int)

package main

import (
	"fmt"
	"sort"
)

type Student struct {
	Number   string
	Name     string
	Age      int
	IsWalker bool
	Weight   float32
}

type ByNumber []*Student

func (this ByNumber)Len() int  {
	return len(this)
}

func (this ByNumber)Less(i,j int) bool  {
	return this[i].Number<this[j].Number
}

func (this ByNumber)Swap(i,j int) {
	this[i],this[j] = this[j],this[i]
}

func (this ByNumber) String() string {
	const  format = "| %v |\t%v |\t%v |\t %v |\t %v |\t%v   |\n"
    fmt.Println("\t\t\t\t\t学生信息表")
    fmt.Println(" 序号\t学号 \t姓名\t   年龄\t  体重\t   是否走读")
	for k,v:=range this{
		fmt.Printf(format,k+1,v.Number,v.Name,v.Age,v.Weight,v.IsWalker)
	}
	return ""
}

func main1() {
	sts:=[]*Student{
		&Student{Number: "003",Name: "张三"},
		&Student{Number: "004",Name: "张四"},
		&Student{Number: "001",Name: "张一"},
		&Student{Number: "002",Name: "张二"},
		&Student{Number: "000",Name: "张零"},
	}
	b:=ByNumber(sts)
	sort.Sort(b)
	fmt.Println(b)
	fmt.Println("反转")
	sort.Sort(sort.Reverse(b))  //反转的用法
	fmt.Println(b)

	//为结构体内的每一个字段都绑定一个排序的外壳,这种操作显然不是很聪明
    //这时候使用组合来解决这个问题
}

type customSort struct {
	s []*Student
	less func(i,j *Student)  bool
}

func (this *customSort)Len() int {
	return len(this.s)
}

func (this *customSort)Swap(i,j int) {
	this.s[i],this.s[j] = this.s[j],this.s[i]
}

func (this *customSort)Less(i,j int) bool {
	return this.less(this.s[i],this.s[j])
}

func main()  {
	sts:=[]*Student{
		&Student{Number: "003",Name: "张三"},
		&Student{Number: "004",Name: "张四"},
		&Student{Number: "001",Name: "张一"},
		&Student{Number: "000",Name: "张二"},
		&Student{Number: "002",Name: "张二"},
	}

	c:=&customSort{
		s: sts,
		less: func(i, j *Student) bool {
			if i.Number != j.Number {    //可以指定多种排序规则
				return i.Number>j.Number
			}
			if i.Name!=j.Name{
				return i.Name<j.Name
			}
			return false
		},
	}

	/*
	package sort
	// A type, typically a collection, that satisfies sort.Interface can be
	// sorted by the routines in this package. The methods require that the
	// elements of the collection be enumerated by an integer index.
	type Interface interface {
		// Len is the number of elements in the collection.
		Len() int
		// Less reports whether the element with
		// index i should sort before the element with index j.
		Less(i, j int) bool
		// Swap swaps the elements with indexes i and j.
		Swap(i, j int)
	}
*/
	sort.Sort(c) //Sort方法中不只能放slice类型,还可以放结构体类型,只要改类型 实现 Sort接口
	fmt.Println(ByNumber(sts)) //单纯的使用一下ByNumber中重写是String()方法
}

总结

到此这篇关于golang中按照结构体的某个字段排序的文章就介绍到这了,更多相关golang按字段排序内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • golang 各种排序大比拼实例

    1.准备工作 准备数据: 生成随机数并写入文件,之后在把数据读取出来 //新生成整数随机数,并存储在txt文件中, func NewIntRandm(fileName string, number, maxrandm int) { filename := fileName file, err := os.Create(filename) if err != nil { return } r := rand.New(rand.NewSource(time.Now().UnixNano())) ra

  • golang 数组随机排序的实现

    目录 前言 具体实现步骤如下 1.引入库 2.组装数据并排序(方案一) 3.组装数据并排序(方案二) 总结 前言 目前接到一个推荐数据的需求,需要将数据库中获取到的数据进行随机排序后返回给用户.考虑了一下,有两种使用方式,一种是通过数据库 order by rand() ,还有一种就是本文需要使用到的代码处理 具体实现步骤如下 1.引入库 代码如下: import ( "fmt" "math/rand" "time" ) 2.组装数据并排序(方案

  • 深入理解golang的基本类型排序与slice排序

    前言 其实golang的排序思路和C和C++有些差别. C默认是对数组进行排序, C++是对一个序列进行排序, Go则更宽泛一些,待排序的可以是任何对象, 虽然很多情况下是一个slice(分片, 类似于数组),或是包含 slice 的一个对象. 排序(接口)的三个要素: 1.待排序元素个数 n : 2.第 i 和第 j 个元素的比较函数 cmp : 3.第 i 和 第 j 个元素的交换 swap : 乍一看条件 3 是多余的, c 和 c++ 都不提供 swap . c 的 qsort 的用法:

  • golang对自定义类型进行排序的解决方法

    前言 Go 语言支持我们自定义类型,我们大家在实际项目中,常常需要根据一个结构体类型的某个字段进行排序.之前遇到这个问题不知道如何解决,后来在网上搜索了相关问题,找到了一些好的解决方案,此处参考下,做个总结吧. 由于 golang 的 sort 包本身就提供了相应的功能, 我们就没必要重复的造个轮子了,来看看如何利用 sort 包来实现吧. sort包浅谈 golang中也实现了排序算法的包sort包,sort 包 在内部实现了四种基本的排序算法:插入排序(insertionSort).归并排序

  • Golang算法问题之数组按指定规则排序的方法分析

    本文实例讲述了Golang算法问题之数组按指定规则排序的方法.分享给大家供大家参考,具体如下: 给出一个二维数组,请将这个二维数组按第i列(i从1开始)排序,如果第i列相同,则对相同的行按第i+1列的元素排序, 如果第i+1列的元素也相同,则继续比较第i+2列,以此类推,直到最后一列.如果第i列到最后一列都相同,则按原序排列. 样例输入: 1,2,3 2,3,4 2,3,1 1,3,1 按第2列排序,输出: 1,2,3 2,3,1 1,3,1 2,3,4 代码实现: 复制代码 代码如下: pac

  • golang编程开发使用sort排序示例详解

    golang sort package: https://studygolang.com/articles/3360 sort 操作的对象通常是一个 slice,需要满足三个基本的接口,并且能够使用整数来索引 // A type, typically a collection, that satisfies sort.Interface can be // sorted by the routines in this package. The methods require that the /

  • golang中按照结构体的某个字段排序实例代码

    目录 概述 从大到小排序 按照结构体的某个字段排序 使用 sort.Stable 进行稳定排序 附:根据结构体中任意字段进行排序 总结 概述 golang的sort包默认支持int, float64, string的从小大到排序: int -> Ints(x []int)float64 -> Float64s(x []float64)string -> Strings(x []string) 同时它还提供了自定义的排序接口Interface,此接口保护三个方法. type Interfa

  • golang结构体与json格式串实例代码

    具体代码如下所示: package main import ( "encoding/json" "fmt" ) type IT struct { //一定要注意这里的成员变量的名字首字母必须是大写 Company string Subjects []string Isok bool Price float64 } func main() { s := IT{"zyg", []string{"go", "python&

  • c++ STL之list对结构体的增加,删除,排序等操作详解

    对STL中的list进一步学习,编程过程中对结构体的操作很多. 全部代码如下: /* Project:list对结构体的使用 Date: 2018/07/14 Author: Frank Yu 常用函数:int size() 返回容器元素个数:bool empty() 判断容器是否为空,true为空: 增加函数:void push_back(元素) 尾元素后增加一个元素:push_front(元素) 首元素前增加一个元素: iterator insert(lit,元素)在迭代器指针lit前插入元

  • 浅谈Go语言中的结构体struct & 接口Interface & 反射

    结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struct类型理解为类,可以定义方法,和函数定义有些许区别: struct类型是值类型. struct定义 type User struct { Name string Age int32 mess string } var user User var user1 *User = &User{} var user2 *User = new(User) struct使用 下面示例中user1和

  • golang gorm模型结构体的定义示例

    目录 1. 模型 1.1. 模型定义 2. 约定 2.1. gorm.Model 结构体 2.2. 表名是结构体名称的复数形式 2.3. 更改默认表名 2.4. 列名是字段名的蛇形小写 2.5. 字段ID为主键 2.6. 字段CreatedAt用于存储记录的创建时间 2.7. 字段UpdatedAt用于存储记录的修改时间 2.8. 字段DeletedAt用于存储记录的删除时间,如果字段存在 1. 模型 1.1. 模型定义 type User struct { gorm.Model Birthda

  • Golang打印复杂结构体两种方法详解

    目录 fmt结构体占位符 打印复杂结构体 方案一 方案二 fmt结构体占位符 在Golang中有原生的 fmt 格式化工具去打印结构体,可以通过占位符%v.%+v.%#v去实现,这3种的区别如下所示: type User struct { Name string Age int } func main() { user := User{ Name: "张三", Age: 95, } fmt.Printf("%v\n", user) fmt.Printf("

  • C语言中的结构体在Python中实现转换

    目录 struct介绍 struct中的常用接口 pack() unpack() fmt 示例 struct介绍 Python中提供了struct接口,用来处理类似C语言中的结构体. 处理的方式是将结构体表现位字符串,这个字符串其实就是结构体的一个个字节. struct中的常用接口 主要就是两个,pack()和unpack(). pack()就是将结构体转换成字符串(或者说字节序),unpack()则相反. pack() pack()函数的说明如下(来自Python 2.7.15 documen

  • C语言 结构体数组详解及示例代码

    所谓结构体数组,是指数组中的每个元素都是一个结构体.在实际应用中,结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生.一个车间的职工等. 定义结构体数组和定义结构体变量的方式类似,请看下面的例子: struct stu{ char *name; //姓名 int num; //学号 int age; //年龄 char group; //所在小组 float score; //成绩 }class[5]; 表示一个班级有5个学生. 结构体数组在定义的同时也可以初始化,例如: str

  • Android List(集合)中的对象以某一个字段排序案例

    在Android开发中,有时我们需要对一个对象的集合按照某一个字段进行排序, Bean public class Student { private int studentId; private String studentName; private int age; public Student(int studentId , String studentName, int age){ this.studentId=studentId; this.studentName=studentName

  • c++ qsort 与sort 对结构体排序实例代码

    #include<bits/stdc++.h> using namespace std; typedef struct { string book; int num; }Book; //qsort的比较函数 int cmp(const void * a, const void * b) { return (*(Book*)a).num > (*(Book*)b).num ? 1 : 0; } //sort的比较函数 bool cmp_(Book a, Book b) { return a

随机推荐