1. 程式人生 > >[Golang] 實現一個通用的排序方式(對任意資料型別構成的slice排序)

[Golang] 實現一個通用的排序方式(對任意資料型別構成的slice排序)

前言:

Go 語言中排序主要使用的sort庫,對於常見資料型別string, int ,float構成的Slice,可以使用sort庫對應的sort.Strings() / sort.Ints() / sort.Float64s()直接排序,但是對於複雜型別struct構成的Slice,要對其排序就需要自己實現其三個方法(Len, Swap,Less)。

問題在於:一個結構體我可以給他寫三個方法,那10個結構體我得寫30個方法?

這一定是不合理的,辦法總比困難多,本文結合 【WangC.W】-- go語言的排序、結構體排序 一文以及自己的理解實現了一臺通用的golang排序寫法。

正文:

package main

import (
	"fmt"
	"sort"
)

//待排序的結構體
type City struct {
	Name 	string
	Number 	int
	Test 	bool
}

//待排序的結構體
type Animal struct {
	Name 	string    // 名字
	Height  float32    // 高度
	Weight 	float32  //體重
}

//定義一個通用的結構體
type Bucket struct {
	Slice []interface{}  //承載以任意結構體為元素構成的Slice
	By func(a,b interface{})bool  //排序規則函式,當需要對新的結構體slice進行排序時,只需定義這個函式即可
}
/*
定義三個必須方法的準則:接收者不能為指標
*/
func (this Bucket)Len()int { return len(this.Slice)}

func (this Bucket)Swap(i,j int){ this.Slice[i],this.Slice[j] = this.Slice[j],this.Slice[i] }

func (this Bucket)Less(i,j int)bool { return this.By(this.Slice[i], this.Slice[j]) }


func main() {
    
    //對第一個結構體排序
	c1 := City{"Los Angeles",1024, true}
	c2 := City{"Wellington",128,false}
	c3 := City{"Seattle",64,false}

	//定義專屬的排序函式
	city_by := func(a,b interface{})bool {
		return a.(City).Number > b.(City).Number   //按年齡排倒序
	}
	citys := Bucket{}
	citys.Slice = append(citys.Slice, c1,c2,c3)
	citys.By = city_by
	sort.Sort(citys)
	fmt.Printf("%+v\n", citys.Slice)


	/***************對第二個結構體排序*****************/
	a1 := Animal{"pigeon",0.15,3}
	a2 := Animal{"sheep",1,20}
	a3 := Animal{"giraffe",3,70}

	//定義結構體Animal的專屬排序函式 -- 關鍵程式碼
	animal_by := func(a,b interface{})bool {
		return a.(Animal).Weight > b.(Animal).Weight  //按體重排倒序
	}
	animals := Bucket{}
	animals.Slice = append(animals.Slice, a1,a2,a3)
	animals.By = animal_by // -- 關鍵程式碼
	sort.Sort(animals) // -- 關鍵程式碼
	fmt.Printf("%+v\n", animals.Slice) //已排序的slice
}

再次感謝【WangC.W】-- go語言的排序、結構體排序 。