在golang中排序

时间:2016-12-02 02:03:34

标签: sorting go

我正在使用go lang创建一个离开应用程序。我的结构如下

Leave struct {
        Leaveid     int
        Name        string
        EmployeeId  string
        Applieddate time.Time
        Leavestatus string
    }

休假状态因处理,批准,拒绝,HRA改进,HrDenied,HrProcessing而异。
一般来说,请假排序顺序必须基于应用日期。
我必须能够先显示处理和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"
          },

        ]
  

更新:这是我使用排序包

所做的
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"
  }
]

这里加工下降,HRApproved上升。但这不是我想要的。请帮我解决这个问题。谢谢

2 个答案:

答案 0 :(得分:1)

你需要先按Leavestatus排序,然后再使用applydate,但是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
}

答案 1 :(得分:0)

Leavestatus定义为string似乎非常低效,因为您需要进行字符串比较并复制结构涉及复制Leavestatus,即使它只是一个“枚举”式类型。这也使得引入基于错误的错误变得更容易,因为编译器无法检查你是否正确输入了字符串。

我会为Leavestatus制作一个基于int的类型,例如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()运算符来比较该字段。