Golang 实现结构体数组按多字段排序
发布于: 2020 年 07 月 19 日
近期因项目重构(php->golang),涉及到一些将对象列表中的对象按不同的字段(属性)排序;
在php中,可以使用usort + 自定义的排序函数轻松实现;
[usort官方文档](https://www.php.net/manual/zh/function.usort.php)
下面我们先看一个在php中的例子:
下面是一个待排序待数组
<?php $result = array( array( "val" => "f", "mtime" => 1595144638, "orderval"=>4 ), array( "val" => "d", "mtime" => 1595144646, "orderval"=>2 ), array( "val" => "a", "mtime" => 1595144648, "orderval"=>8 ), array( "val" => "t", "mtime" => 1595144648, "orderval"=>5 ), array( "val" => "e", "mtime" => 1595144650, "orderval"=>3 ) );
我们目前待目标是将该数组中待对象
按mtime 从大到小排序;如果mtime字段
的值相等,则按orderval从大到小排,最终想要的结果为:
e,a,t,d,f
[ {"val"=>"e","mtime"=>1595144650,"orderval"=>3}, {"val"=>"a","mtime"=>1595144648,"orderval"=>8}, {"val"=>"t","mtime"=>1595144648,"orderval"=>5}, {"val"=>"d","mtime"=>1595144646,"orderval"=>2}, {"val"=>"f","mtime"=>1595144638,"orderval"=>4}]
我们首先定义一个自定义函数,然后巧妙使用usort函数去调用的自定义函数,最终实现目标,直接上代码:
php $result = array( array( "val" => "f", "mtime" => 1595144638, "orderval"=>4 ), array( "val" => "d", "mtime" => 1595144646, "orderval"=>2 ), array( "val" => "a", "mtime" => 1595144648, "orderval"=>8 ), array( "val" => "t", "mtime" => 1595144648, "orderval"=>5 ), array( "val" => "e", "mtime" => 1595144650, "orderval"=>3 ) ); //按mtime 从大到小;如果mtime 相等,则按orderval 从大到小; usort($result, function ($v1, $v2) { if ($v1['mtime'] < $v2['mtime'] || ($v1['mtime'] == $v2['mtime'] && $v1['orderval'] < $v2['orderval'])) { return 1; } else { return -1; } }); var_dump($result);
运行结果:
array(5) { [0]=> array(3) { ["val"]=> string(1) "e" ["mtime"]=> int(1595144650) ["orderval"]=> int(3) } [1]=> array(3) { ["val"]=> string(1) "a" ["mtime"]=> int(1595144648) ["orderval"]=> int(8) } [2]=> array(3) { ["val"]=> string(1) "t" ["mtime"]=> int(1595144648) ["orderval"]=> int(5) } [3]=> array(3) { ["val"]=> string(1) "d" ["mtime"]=> int(1595144646) ["orderval"]=> int(2) } [4]=> array(3) { ["val"]=> string(1) "f" ["mtime"]=> int(1595144638) ["orderval"]=> int(4) }}
那么同样的功能,如果要用golang来实现,应如何办呢?
下面我们首先讲讲golang 官方对排序 对支持,然后给出具体对例子;
……
……
package mainimport ( "fmt" "sort")type Obj struct { Var string `json:"var"` Mtime int `json:"mtime"` Orderval int `json:"orderval"`}type List []Objfunc (p List) Len() int { return len(p)}func (p List) Less(i, j int) bool { if p[i].Mtime > p[j].Mtime { return true } if p[i].Mtime < p[j].Mtime { return false } return p[i].Orderval > p[j].Orderval}func (p List) Swap(i, j int) { p[i], p[j] = p[j], p[i]}func (p *List) Sort() { sort.Sort(p)}func main() { s := List{{"f", 1595144638, 4}, {"d", 1595144646, 2}, {"a", 1595144648, 8}, {"t", 1595144648, 5}, {"e", 1595144650, 3}} fmt.Println(s) s.Sort() fmt.Println(s)}
划线
评论
复制
发布于: 2020 年 07 月 19 日 阅读数: 101
版权声明: 本文为 InfoQ 作者【卓丁】的原创文章。
原文链接:【http://xie.infoq.cn/article/1a029cd083c699618cf98f54f】。文章转载请联系作者。
卓丁
关注
鸟过无痕 2017.12.10 加入
泰戈尔:虽然天空没有留下我的痕迹,但我已飞过。
评论