【Golang实战】slice自定义字段排序

这个资料真的难找,搜了一圈,基本都是一样的,都是讲怎么通过反射改变slice中的值,关于自定义字段排序的资料缺是一个也没有。

这也难怪,如果不是为了重构一个方法,关于排序复用代码太多,我也不会查找这方面的资料,并通过实践测试,找到了相关的方法。

源码真的是一个非常非常好的参考资料。在找不到相关自定义字段排序的资料下,我翻了一下 sort.Slice 相关的源码,确定了如果要用反射排序,则需要使用 relfect.ValueOf 方法获取需要排序的内容,如下

// Slice sorts the provided slice given the provided less function.
//
// The sort is not guaranteed to be stable. For a stable sort, use
// SliceStable.
//
// The function panics if the provided interface is not a slice.
func Slice(slice interface{}, less func(i, j int) bool) {
	rv := reflectValueOf(slice)
	swap := reflectSwapper(slice)
	length := rv.Len()
	quickSort_func(lessSwap{less, swap}, 0, length, maxDepth(length))
}

并通过资料以及尝试,确定 reflect.Valueof.Index 方法可以获取反射内容的相关值,最终得到通过反射来自定义字段排序的结论代码,示例如下:

代码:

type Str struct {
	A string
	V int
}

func TestBindParams(t *testing.T) {
	var tt = []Str{{A: "test A", V: 2}, {A: "test b", V: 1}, {A: "test c", V: -1}}
	f := "V"
	sort.Slice(tt, func(i, j int) bool {
		tmp := reflect.ValueOf(tt)
        // 指针与结构体获取反射字段值的用法不一样
		if tmp.Type().Elem().Kind() == reflect.Ptr {
			return tmp.Index(i).Elem().FieldByName(f).Int() < tmp.Index(j).Elem().FieldByName(f).Int()
		}
		return tmp.Index(i).FieldByName(f).Int() < tmp.Index(j).FieldByName(f).Int()
	})
	t.Log(tt)
}

输出:

=== RUN   TestBindParams
    TestBindParams: http_test.go:153: [{test c -1} {test b 1} {test A 2}]
--- PASS: TestBindParams (0.00s)
PASS

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值