golang 结构体数组,多条件排序

golang 结构体数组,多条件排序,第1张

需要重写sort包下的Interface接口方法。

如下为示例:

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"reflect"
	"sort"
	"time"

	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/transform"
)

const (
	FORMAT_DATETIME = "2006-01-02 15:04:05"
)

func main() {
two := []*Two{
		{FirstFiled: "2021-05-13 17:04:05", SecondField: "十年"},
		{FirstFiled: "2021-05-13 15:04:05", SecondField: "综合"},
		{FirstFiled: "2021-05-13 15:04:05", SecondField: "大家"},
		{FirstFiled: "2021-05-13 16:04:05", SecondField: "大家"},
		{FirstFiled: "2021-05-13 15:04:05", SecondField: "鸣人"},
		{FirstFiled: "2021-05-13 15:04:05", SecondField: "小樱"},
	}
	SortWithTwoItems(two, "FirstFiled", "SecondField")
	for _, v := range two {
		fmt.Println("after sorted with two items ps -- ", *v)
	}
}

type Two struct {
	FirstFiled  string
	SecondField string
}

//UTF82GBK : transform UTF8 rune into GBK byte array
func UTF82GBK(src string) ([]byte, error) {
	GB18030 := simplifiedchinese.All[0]
	return ioutil.ReadAll(transform.NewReader(bytes.NewReader([]byte(src)), GB18030.NewEncoder()))
}

//根据两个条件排序,先根据时间排序,再根据姓名字母排序
//Data 为需要排序的结构体数组
//FirstField为时间字段名
//SecondFied为姓名字段名
type TwoItems struct {
	Data        interface{}
	FirstField  string
	SecondField string
}

func (items *TwoItems) Len() int {
	if reflect.ValueOf(items.Data).Kind() != reflect.Slice {
		return -1
	}
	return reflect.ValueOf(items.Data).Len()
}

func (items *TwoItems) Less(i, j int) bool {
	a := reflect.ValueOf(items.Data).Index(i)
	b := reflect.ValueOf(items.Data).Index(j)
	if a.Kind() == reflect.Ptr {
		a = a.Elem()
	}
	if b.Kind() == reflect.Ptr {
		b = b.Elem()
	}
	vta := a.FieldByName(items.FirstField).String()
	vtb := b.FieldByName(items.FirstField).String()
	ta, err := time.Parse(FORMAT_DATETIME, vta)
	if err != nil {
		return false
	}
	tb, err := time.Parse(FORMAT_DATETIME, vtb)
	if err != nil {
		return false
	}
	vga := a.FieldByName(items.SecondField).String()
	vgb := b.FieldByName(items.SecondField).String()
	ga, _ := UTF82GBK(vga)
	gb, _ := UTF82GBK(vgb)
	bLen := len(gb)
	if ta.Before(tb) {
		return true
	} else {
		if ta.Equal(tb) {
			for idx, chr := range ga {
				if idx > bLen-1 {
					return false
				}
				if chr != gb[idx] {
					return chr < gb[idx]
				}
			}
		} else {
			return false
		}
	}
	return ta.Before(tb)
}

func (items *TwoItems) Swap(i, j int) {
	reflect.Swapper(items.Data)(i, j)
}

func SortWithTwoItems(i interface{}, firstField, secondField string) {
	if reflect.ValueOf(i).Kind() != reflect.Slice {
		return
	}
	a := &TwoItems{
		Data:        i,
		FirstField:  firstField,
		SecondField: secondField,
	}
	sort.Sort(a)
}

输出结果如下:

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/995986.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存