【GoLang】【工具分享】1、根据 JsonTag 对 slice 进行稳定排序(不支持嵌套)

这篇具有很好参考价值的文章主要介绍了【GoLang】【工具分享】1、根据 JsonTag 对 slice 进行稳定排序(不支持嵌套)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、背景

后端返回 List 列表中的 Json 序列化结构到前端,其中包含许多字段,业务需求可以按照某个字段对列表数据做 升/降序排序。

2、代码实现

前端将后端返回的 Json 关键字及排序方向作为参数传递至后端即可,后端根据 Json 排序关键字找到对应的 JsonTag 后,采用反射找到字段,再写自定义排序函数即可实现指定字段的排序。

Go 代码:

func SliceSortByJsonTag(slice interface{}, tagName string, ascending bool) {
    value := reflect.ValueOf(slice)
    typ := value.Type().Elem()

    // 匹配不到指定的 jsonTag 则不进行排序
    if name := getFieldName(typ, tagName); len(name) > 0 {
        sort.SliceStable(slice, func(i, j int) bool {
            fieldI := value.Index(i).FieldByName(name)
            fieldJ := value.Index(j).FieldByName(name)

            switch fieldI.Kind() {
            case reflect.String:
                if ascending {
                    return fieldI.String() < fieldJ.String()
                } else {
                    return fieldI.String() > fieldJ.String()
                }
            case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
                if ascending {
                    return fieldI.Int() < fieldJ.Int()
                } else {
                    return fieldI.Int() > fieldJ.Int()
                }
            case reflect.Float32, reflect.Float64:
                if ascending {
                    return fieldI.Float() < fieldJ.Float()
                } else {
                    return fieldI.Float() > fieldJ.Float()
                }
            default:
                return false
            }
        })
    }
}

func getFieldName(typ reflect.Type, tagName string) string {
    for i := 0; i < typ.NumField(); i++ {
        field := typ.Field(i)
        if field.Tag.Get("json") == tagName {
            return field.Name
        }
    }

    return ""
}

单元测试:文章来源地址https://www.toymoban.com/news/detail-533366.html


type Person struct {
    Name   string `json:"name"`
    Age    int    `json:"age"`
    Gender string `json:"gender"`
}

func TestSliceSortByJsonTag(t *testing.T) {
    tests := []struct {
        name          string
        persons       []Person
        tagName       string
        ascending     bool
        expectedOrder []Person
    }{
        {
            name: "按姓名升序排序",
            persons: []Person{
                {Name: "Bob", Age: 30, Gender: "male"},
                {Name: "Alice", Age: 25, Gender: "female"},
                {Name: "Charlie", Age: 20, Gender: "male"},
            },
            tagName: "name",
            ascending: true,
            expectedOrder: []Person{
                {Name: "Alice", Age: 25, Gender: "female"},
                {Name: "Bob", Age: 30, Gender: "male"},
                {Name: "Charlie", Age: 20, Gender: "male"},
            },
        },
        {
            name: "按年龄降序排序",
            persons: []Person{
                {Name: "Bob", Age: 30, Gender: "male"},
                {Name: "Alice", Age: 25, Gender: "female"},
                {Name: "Charlie", Age: 20, Gender: "male"},
            },
            tagName: "age",
            ascending: false,
            expectedOrder: []Person{
                {Name: "Bob", Age: 30, Gender: "male"},
                {Name: "Alice", Age: 25, Gender: "female"},
                {Name: "Charlie", Age: 20, Gender: "male"},
            },
        },
        {
            name: "按性别升序排序",
            persons: []Person{
                {Name: "Bob", Age: 30, Gender: "male"},
                {Name: "Alice", Age: 25, Gender: "female"},
                {Name: "Charlie", Age: 20, Gender: "male"},
            },
            tagName: "gender",
            ascending: true,
            expectedOrder: []Person{
                {Name: "Alice", Age: 25, Gender: "female"},
                {Name: "Bob", Age: 30, Gender: "male"},
                {Name: "Charlie", Age: 20, Gender: "male"},
            },
        },
        {
            name: "未匹配到指定tag,不进行排序",
            persons: []Person{
                {Name: "Bob", Age: 30, Gender: "male"},
                {Name: "Alice", Age: 25, Gender: "female"},
                {Name: "Charlie", Age: 20, Gender: "male"},
            },
            tagName: "xxxx",
            ascending: true,
            expectedOrder: []Person{
                {Name: "Bob", Age: 30, Gender: "male"},
                {Name: "Alice", Age: 25, Gender: "female"},
                {Name: "Charlie", Age: 20, Gender: "male"},
            },
        },
    }

    for _, test := range tests {
        t.Run(test.name, func(t *testing.T) {
            persons := make([]Person, len(test.persons))
            copy(persons, test.persons)

            SliceSortByJsonTag(persons, test.tagName, test.ascending)

            if !reflect.DeepEqual(persons, test.expectedOrder) {
                t.Errorf("Sorting failed.\nExpected: %v\nGot: %v", test.expectedOrder, persons)
            }
        })
    }
}

3、工具改进

  • 可考虑支持 Json 嵌套结构的排序
  • 支持更多数据类型

到了这里,关于【GoLang】【工具分享】1、根据 JsonTag 对 slice 进行稳定排序(不支持嵌套)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 使用stream流对List<Map<String, Object>>集合根据value进行排序

    第一步:初始化数据 ========================================================= 第二步:开始排序 ① 根据数字排序 打印结果 ② 根据字符串排序 打印结果 ③ 根据时间类型排序 打印结果 总结:String类型是万金油的排序方式,基本都可以用!!! 补充一个排序方法 打印结果 就这样。。。

    2024年02月16日
    浏览(39)
  • Golang学习——string和slice切片

    Golang学习——string和slice切片

    1个字节可以表示256个数字,2个字节可以表示65536个数字 字符集:字符编号对照表。收录很多数字,给它们一一编号。 字符集的更迭 全球化统一标准——通用字符集 于1990年开始研发并于1994年正式公布,实现了跨语言跨平台的文本转换与处理。 字符集促成了字符与二进制的

    2024年02月15日
    浏览(8)
  • golang slice 作为参数值传递情况说明

    golang 中引用类型有:slice、map、interface、channel golang所有类型在函数中都是值传递,这个跟上面golang中有的数据类型为引用类型并不冲突,用下面四个slice实例帮助理解 说明: main 函数中slice[0]说明 fn 函数里面的修改,也改变函数外的值,这跟slice为引用类型的缘故 说明:s

    2024年02月15日
    浏览(8)
  • 【视频】Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析|数据分享...

    【视频】Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析|数据分享...

    在本文中,长短期记忆网络——通常称为“LSTM”——是一种特殊的RNN递归神经网络,能够学习长期依赖关系 ( 点击文末“阅读原文”获取完整 代码数据 ) 。 视频:LSTM 神经网络架构和工作原理及其在Python中的预测应用 什么是依赖关系? 假设您在观看视频时记得前一个场

    2024年02月11日
    浏览(11)
  • Golang 中的数组Array以及Slice底层实现

    Golang 中的数组Array以及Slice底层实现

    数组是指一系列同一类型数据的集合。数组中包含的每个数据被称为数组元素 (element),这种类型可以是任意的原始类型,比如 int 、 string 等,也可以是用户自定义的类型。一个数组包含的元素个数被称为数组的长度。 在 Golang 中数组是一个长度固定的数据类型, 数组的长度

    2024年02月16日
    浏览(10)
  • Golang 中的 slice 为什么是并发不安全的?

    Golang 中的 slice 为什么是并发不安全的?

      在Go语言中,slice是并发不安全的,主要有以下两个原因:数据竞争、内存重分配。   数据竞争:slice底层的结构体包含一个指向底层数组的指针和该数组的长度,当多个协程并发访问同一个slice时,有可能会出现数据竞争的问题。例如,一个协程在修改slice的长度,而

    2024年02月05日
    浏览(15)
  • 为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

    为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

    Fasthttp 是一个高性能的 Golang HTTP 框架,它在设计上做了许多优化以提高性能。其中一个显著的设计选择是使用 slice 而非 map 来存储数据,尤其是在处理 HTTP headers 时。 为什么呢? 本文将从简单到复杂,逐步剖析为什么 Fasthttp 选择使用 slice 而非 map,并通过代码示例解释这一

    2024年01月22日
    浏览(11)
  • 稳定的排序算法:直接插入排序和冒泡排序 (c++实现)

    1.直接插入排序: 插入排序:就是把数组分为左右两个序列,保持左边序列中所有元素是有序的,(当左边序列只有第一个元素时,本身就是有序的,)每次往后移一个,将这个元素保存起来,跟左边的元素进行比较,直到找到第一个小于它的元素后停下,此时的位置是这个

    2024年02月10日
    浏览(9)
  • numpy argsort排序如何让其稳定排序

    numpy. argsort ( a ,  axis = -1 ,  kind = None ,  order = None ) Parameters : a array_like Array to sort. axis  int or None, optional Axis along which to sort. The default is -1 (the last axis). If None, the flattened array is used. kind  {‘quicksort’, ‘mergesort’, ‘heapsort’, ‘stable’}, optional Sorting algorithm. The default is ‘quic

    2024年02月14日
    浏览(11)
  • 【八大排序(十)】八大排序效率与稳定性分析

    【八大排序(十)】八大排序效率与稳定性分析

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:八大排序专栏⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习排序知识   🔝🔝 比较八大排序不能直接将 这八个排序放在一起讨论 我们根据大致效率将它们分为两组: (每个排序的详情链接在后面) 1. 第一组 插入排

    2024年02月11日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包