doucan4815 2016-06-16 09:27
浏览 69
已采纳

在Go lang中按动态字段排序

So I'm struggling to figure out how to sort following structure by "status" field (asc, desc)

type CampaignStatus struct {
    Campaign CampaignData
    Status   string `json:"status" bson:"status"`
}

type CampaignsPagination struct {
    Pagination PageMetadata  `json:"pagination"`
    Campaigns  []CampaignStatus `json:"campaigns"`
}

Example json of full campaigns pagination:

   "pagination": {
        "page": 1,
        "per_page": 15,
        "page_count": 1,
        "total_count": 4
    },
    "campaigns": [
        {
            "Campaign": {
                "_id": "57597fc6799e0fe41d0eede6",
                "name": "Test campaign",
                "description": "Just test campaign"
                "isEmail": true
            },
            "status": "expired"
        },
        ...
    }

So my function is retuting variable ret := &CampaignsPagination{} which is filled with data from mongoDB but status is determinated by other stuff in realtime. So reflect package is saying that I'm trying to sort type of *CampaignsPagination and everything what I use pretty much ends with errors like "type CampaignsPagination does not support indexing" (using sort packag) any hints are more then welcome

Update:

How I try to sort this (but it won't compile due to (type *CampaignsPagination does not support indexing

func (a *CampaignsPagination) Len() int {
    return len(a)
}
func (a *CampaignsPagination) Swap(i, j int) {
    a[i], a[j] = a[j], a[i]
}
func (a *CampaignsPagination) Less(i, j int) bool {
    if a[i].Status < a[j].Status {
        return true
    }
    if a[i].Status > a[j].Status {
        return false
    }
    return a[i].Status < a[j].Status
}
  • 写回答

2条回答 默认 最新

  • duanqian6982 2016-06-16 10:03
    关注

    Usually sorting is defined on a slice. You try to define sorting on your CampaignsPagination struct type.

    This can also be done, but it's a little unusal (e.g. what would you do if you decide you want to have another order based on another field?). Since your receiver a is not a slice but a (pointer to a) wrapper struct, when indexing and returning the length, use the slice a.Campaigns. Also string values are comparable and ordered (lexically byte-wise). So you can simply compare CampaignStatus.Status values and return the result in Less().

    func (a *CampaignsPagination) Len() int {
        return len(a.Campaigns)
    }
    func (a *CampaignsPagination) Swap(i, j int) {
        a.Campaigns[i], a.Campaigns[j] = a.Campaigns[j], a.Campaigns[i]
    }
    func (a *CampaignsPagination) Less(i, j int) bool {
        return a.Campaigns[i].Status < a.Campaigns[j].Status
    }
    

    A more logical solution would be to define the sorting on a slice, e.g.:

    type CampaignStatusSort []CampaignStatus
    
    func (c CampaignStatusSort) Len() int { return len(c) }
    
    func (c CampaignStatusSort) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
    
    func (c CampaignStatusSort) Less(i, j int) bool { return c[i].Status < c[j].Status }
    

    And then if you have a value of type *CampaignsPagination, you can sort the campaigns like this:

    cp := &CampaignsPagination{} // Init struct
    
    sort.Sort(CampaignStatusSort(cp.Campaigns))
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的