【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日
    浏览(33)
  • Golang学习——string和slice切片

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    2024年02月11日
    浏览(39)
  • 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日
    浏览(28)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包