英文:
Sorting in golang
问题
我正在使用Go语言创建一个请假申请。我的结构如下:
type Leave struct {
Leaveid int
Name string
EmployeeId string
Applieddate time.Time
Leavestatus string
}
请假状态有多种,包括Processing、Approved、Denied、HRApproved、HrDenied和HrProcessing。通常情况下,请假排序应该基于申请日期。我希望能够首先显示Processing和HRProcessing状态,然后显示其他状态类型。
你想要的结果类似于:
[
{
"Leaveid": 4,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T08:59:02.870882+08:00",
"Leavestatus": "HRProcessing"
},
{
"Leaveid": 1,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T07:30:01.679636+08:00",
"Leavestatus": "Processing"
},
{
"Leaveid": 3,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T07:00:02.870882+08:00",
"Leavestatus": "HRProcessing"
},
{
"Leaveid": 5,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T10:00:11.139189+08:00",
"Leavestatus": "Approved"
},
{
"Leaveid": 2,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T07:58:41.837666+08:00",
"Leavestatus": "HRApproved"
}
]
更新:这是我使用sort包完成的代码:
type leaveDetails []Leave
func (sortleave leaveDetails) Len() int {
return len(sortleave)
}
func (sortleave leaveDetails) Less(i, j int) bool {
if sortleave[i].Applieddate.After(sortleave[j].Applieddate) {
return true
}
if sortleave[i].Applieddate.Before(sortleave[j].Applieddate) {
return false
}
return sortleave[i].Leavestatus > sortleave[j].Leavestatus
}
func (sortleave leaveDetails) Swap(i, j int) {
sortleave[i], sortleave[j] = sortleave[j], sortleave[i]
}
输出结果为:
[
{
"Leaveid": 2,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T08:59:45.139189+08:00",
"Leavestatus": "HRProcessing"
},
{
"Leaveid": 4,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T08:59:02.870882+08:00",
"Leavestatus": "HRApproved"
},
{
"Leaveid": 3,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T08:58:41.837666+08:00",
"Leavestatus": "Processing"
},
{
"Leaveid": 1,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-01T18:10:01.679636+08:00",
"Leavestatus": "Processing"
}
]
在这个结果中,Processing状态被放在了后面,而HRApproved状态被放在了前面。但这不是你想要的结果。请帮助我解决这个问题。谢谢!
英文:
I am creating a leave application using go lang.<be>My struct is as follows
Leave struct {
Leaveid int
Name string
EmployeeId string
Applieddate time.Time
Leavestatus string
}
The Leave status varies between Processing ,Approved ,Denied, HRApproved, HrDenied, HrProcessing. <br>By general the leave sort order must be based on applied date.<br>I must be able to show the Processing and HRProcessing first and other status types later.
I want something like this
[
{
"Leaveid": 4,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T08:59:02.870882+08:00",
"Leavestatus": "HRProcessing"
},
{
"Leaveid": 1,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T07:30:01.679636+08:00",
"Leavestatus": "Processing"
},
{
"Leaveid": 3,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T07:00:02.870882+08:00",
"Leavestatus": "HRProcessing"
},
{
"Leaveid": 5,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T10:00:11.139189+08:00",
"Leavestatus": "Approved"
},
{
"Leaveid": 2,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T07:58:41.837666+08:00",
"Leavestatus": "HRApproved"
},
]
> Update:This is what i have done using sort package
func (sortleave leaveDetails) Len() int {
return len(sortleave)
}
func (sortleave leaveDetails) Less(i, j int) bool {
if sortleave[i].Applieddate.After(sortleave[j].Applieddate) {
return true
}
if sortleave[i].Applieddate.Before(sortleave[j].Applieddate) {
return false
}
return sortleave[i].Leavestatus > sortleave[j].Leavestatus
}
func (sortleave leaveDetails) Swap(i, j int) {
sortleave[i], sortleave[j] = sortleave[j], sortleave[i]
}
Output:
[
{
"Leaveid": 2,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T08:59:45.139189+08:00",
"Leavestatus": "HRProcessing"
},
{
"Leaveid": 4,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T08:59:02.870882+08:00",
"Leavestatus": "HRApproved"
},
{
"Leaveid": 3,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-02T08:58:41.837666+08:00",
"Leavestatus": "Processing"
},
{
"Leaveid": 1,
"Name": "rajesh",
"EmployeeId": "rajesh",
"Applieddate": "2016-12-01T18:10:01.679636+08:00",
"Leavestatus": "Processing"
}
]
Here Processing goes down and HRApproved goes up.But this is not what i wanted.Please help me to solve this problem.Thanks
答案1
得分: 1
你需要首先按照Leavestatus进行排序,然后按照applieddate进行排序。但是Leavestatus是一组枚举值,而不是按字母顺序排序的,所以你需要对状态进行分类,看它们是否相同,如果相同,则按日期排序,否则按状态排序。类似这样的代码:
func (d leaveDetails) Less(i, j int) bool {
status := func(l Leave) int {
if l.Leavestatus == "Processing" || l.Leavestatus == "HRProcessing" {
return 1
}
return 2
}
a := status(d[i])
b := status(d[j])
if a == b {
return d[i].Applieddate.After(d[j].Applieddate)
}
return a < b
}
英文:
You need to sort by Leavestatus first,then applieddate, but leavestatus is a set of enums rather than being alpha sorted, so you'll want to catogorize the status, see if they're they same if so, sort by date, otherwise sort by the status. something like
func (d leaveDetails) Less(i, j int) bool {
status := func(l Leave) int {
if l.Leavestatus == "Processing" || l.Leavestatus == "HRProcessing" {
return 1
}
return 2
}
a := status(d[i])
b := status(d[j])
if a == b {
return d[i].Applieddate.After(d[j].Applieddate)
}
return a<b
}
答案2
得分: 0
将Leavestatus
定义为string
似乎效率不高,因为你需要进行字符串比较,并且复制结构体时需要复制Leavestatus
,即使它只是一个类似于"enum"的类型。这也使得引入基于拼写错误的错误更容易,因为编译器无法检查你是否正确输入了字符串。
我会为Leavestatus
创建一个基于整数的类型,例如LeaveStatus
:
type LeaveStatus int
const (
_ = iota
Processing
HRProcessing
HRApproved
)
然后你可以在该类型上定义String()
方法:
func (s LeaveStatus) String() string {
switch(s) {
case Processing:
return "Processing"
case HRProcessing:
return "HRProcessing"
case Approved:
return "Approved"
default:
panic("O_O")
}
}
由于LeaveStatus
现在是基于数字的类型,你可以在Less()
实现中使用<
和>
运算符来比较字段。
英文:
Defining Leavestatus
as a string
seems pretty inefficient since you'd need to do string comparison and copying the struct involves copying the Leavestatus
even though it's just a "enum"-like type. This also makes it easier to introduce typo-based bugs since compiler can't check if you typed strings right.
I would make a int based type for Leavestatus
, e.g. LeaveStatus
type LeaveStatus int
const (
_ = iota
Processing
HRProcessing
HRApproved
)
Then you can have String()
method on the type:
func (s LeaveStatus) String() string {
switch(s) {
case Processing:
return "Processing"
case HRProcessing:
return "HRProcessing"
case Approved:
return "Approved"
default:
panic("O_O")
}
}
Since LeaveStatus
is a number-based type now, you can just compare the field using <
and >
operators in your Less()
implementation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论