arrays - 如何在golang中按动态字段名对结构数组进行排序
问题描述
我想按动态字段对结构数组进行排序。这是结构
type user struct{
Name string `json:"name"`
Age int `json:"age"`
Status int `json:"status "`
Type string `json:"type"`
}
这是一个结构数组
var UserArray []user
我必须按给定字段对这个数组进行排序,该字段可以是用户结构的任何字段。但我会从 UI 接收该排序字段作为 JSON 标记。如下所示
sort := agnutil.GetQueryParamString(<json tag>, "sort", 0, "name")
我已经尝试过 golang 中的排序功能,但是如何动态使用它?
sort.Slice(UserArray , func(i, j int) bool {
return UserArray[i].<givenfield> < UserArray[j].<givenfield>
})
解决方案
我想尝试按字段的 json 标记对结构片段进行排序,这就是我最终得到的结果,以防它对任何人有所帮助:
package main
import (
"fmt"
"reflect"
"sort"
)
func sortBy(jsonField string, arr []num) {
if len(arr) < 1 {
return
}
// first we find the field based on the json tag
valueType := reflect.TypeOf(arr[0])
var field reflect.StructField
for i := 0; i < valueType.NumField(); i++ {
field = valueType.Field(i)
if field.Tag.Get("json") == jsonField {
break
}
}
// then we sort based on the type of the field
sort.Slice(arr, func(i, j int) bool {
v1 := reflect.ValueOf(arr[i]).FieldByName(field.Name)
v2 := reflect.ValueOf(arr[j]).FieldByName(field.Name)
switch field.Type.Name() {
case "int":
return int(v1.Int()) < int(v2.Int())
case "string":
return v1.String() < v2.String()
case "bool":
return !v1.Bool() // return small numbers first
default:
return false // return unmodified
}
})
fmt.Printf("\nsort by %s:\n", jsonField)
prettyPrint(arr)
}
func prettyPrint(arr []num) {
for _, v := range arr {
fmt.Printf("%+v\n", v)
}
}
type num struct {
Id int `json:"id"`
Name string `json:"name"`
Big bool `json:"big"`
}
func main() {
userArray := []num{
{1, "one", false},
{5, "five", false},
{40, "fourty", true},
{9, "nine", false},
{60, "sixty", true},
}
fmt.Println("original:")
prettyPrint(userArray)
sortBy("id", userArray[:])
sortBy("name", userArray[:])
sortBy("big", userArray[:])
}
original:
{Id:1 Name:one Big:false}
{Id:5 Name:five Big:false}
{Id:40 Name:fourty Big:true}
{Id:9 Name:nine Big:false}
{Id:60 Name:sixty Big:true}
sort by id
{Id:1 Name:one Big:false}
{Id:5 Name:five Big:false}
{Id:9 Name:nine Big:false}
{Id:40 Name:fourty Big:true}
{Id:60 Name:sixty Big:true}
sort by name
{Id:5 Name:five Big:false}
{Id:40 Name:fourty Big:true}
{Id:9 Name:nine Big:false}
{Id:1 Name:one Big:false}
{Id:60 Name:sixty Big:true}
sort by big
{Id:1 Name:one Big:false}
{Id:9 Name:nine Big:false}
{Id:5 Name:five Big:false}
{Id:40 Name:fourty Big:true}
{Id:60 Name:sixty Big:true}
推荐阅读
- python - 无法从子目录导入 python 模块
- javascript - JS,如何在特定显示器上启动应用程序?
- vb.net - Visual Basic 中的简单银行应用程序
- postgresql - Docker:postgres与节点之间没有连接
- c++ - 使用 ssh 重新连接到远程 Ubuntu 机器后,如何继续使用 gdb 调试 c++ 代码?
- mysql - 如何使用我的 sql 中具有“日期格式”的列按“月份”排序?
- prolog - Prolog中列表中的重复和双倍元素
- python - Dash,如何根据单击的按钮进行回调?
- mysql - 尝试导入大型 sql 数据库文件时,DBeaver mysql 中出现错误
- python - 在 django 视图中使用时间戳范围过滤错误