I am creating a leave application using go lang.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.
By general the leave sort order must be based on applied date.
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
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
}
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.