按照go

时间:2016-06-16 09:27:33

标签: sorting go

所以我正在努力弄清楚如何按照" 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"`
}

完整广告系列分页的示例json:

   "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"
        },
        ...
    }

所以我的功能是retuting变量ret:=& CampaignsPagination {},它填充了来自mongoDB的数据,但状态是由实时的其他内容决定的。所以反思包说我试图对* CampaignsPagination的类型进行排序,而我使用的所有内容都以#34;类型之类的错误结束;类型CampaignsPagination不支持索引" (使用sort packag)任何提示都更受欢迎

更新

我如何尝试对此进行排序(但由于(类型* CampaignsPagination不支持索引)而无法编译

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 个答案:

答案 0 :(得分:1)

通常在切片上定义排序。您尝试在CampaignsPagination结构类型上定义排序。

这也可以这样做,但它有点不同寻常(例如,如果您决定要根据另一个字段获得另一个订单,您会怎么做?)。由于接收器a不是切片而是(指向a)包装器结构的指针,因此在索引并返回长度时,请使用切片a.Campaignsstring值也是可比较的并且是有序的(词法上是字节顺序的)。因此,您只需比较CampaignStatus.Status值并将结果返回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
}

更合理的解决方案是在切片上定义排序,例如:

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 }

然后,如果您的值为*CampaignsPagination,则可以按以下方式对广告系列进行排序:

cp := &CampaignsPagination{} // Init struct

sort.Sort(CampaignStatusSort(cp.Campaigns))

答案 1 :(得分:0)

CampaignsPaginationStatus之间没有一对一的关系。 CampaignsPagination有一片CampaignStatus作为字段;表示CampaignsPagination有许多Status es。

所以我假设您要对字段Campaigns []CampaignStatus进行排序。你的代码几乎是正确的; CampaignsPagination实现接口sort.Interface

func (x *CampaignsPagination) Len() int {
    return len(x.Campaigns)
}
func (x *CampaignsPagination) Swap(i, j int) {
    a := x.Campaigns
    a[i], a[j] = a[j], a[i]
}
func (x *CampaignsPagination) Less(i, j int) bool {
    a := x.Campaigns
    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
}

但引入可排序类型更合乎逻辑:

type Statuses []CampaignStatus

func (a Statuses) Len() int {
    return len(a)
}
func (a Statuses) Swap(i, j int) {
    a[i], a[j] = a[j], a[i]
}
func (a Statuses) 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
}

然后将其用作字段Campaigns

type CampaignsPagination struct {
    Pagination PageMetadata `json:"pagination"`
    Campaigns  Statuses     `json:"campaigns"`
}