对结构体数组进行排序(缺少 Len 方法)

huangapple go评论92阅读模式
英文:

Sorting array of structs (missing Len method)

问题

我有两个如下所示的结构体:

// DuplicatedAd格式
type DuplicatedAd struct {
// 广告标识符
AdID int form:"ad_id" json:"ad_id,omitempty" xml:"ad_id"
// 广告参数,可以为空
AdParams string form:"ad_params" json:"ad_params,omitempty" xml:"ad_params"
// 广告正文
Body string form:"body" json:"body,omitempty" xml:"body"
// 广告正文重复百分比
BodyScore float64 form:"body_score" json:"body_score,omitempty" xml:"body_score"
// 广告类别
Category int form:"category" json:"category,omitempty" xml:"category"
// 广告上传的主图像
Image string form:"image,omitempty" json:"image,omitempty" xml:"image,omitempty"
// 广告列表ID
ListID int form:"list_id" json:"list_id,omitempty" xml:"list_id"
// 广告列表时间
ListTime string form:"list_time" json:"list_time,omitempty" xml:"list_time"
// 广告电话号码
Phone string form:"phone,omitempty" json:"phone,omitempty" xml:"phone,omitempty"
// 广告地区
Region int form:"region" json:"region,omitempty" xml:"region"
// 广告状态
Status string form:"status" json:"status,omitempty" xml:"status"
// 广告主题
Subject string form:"subject" json:"subject,omitempty" xml:"subject"
// 广告主题重复百分比
SubjectScore float64 form:"subject_score" json:"subject_score,omitempty" xml:"subject_score"
// 广告类型
Type string form:"type" json:"type,omitempty" xml:"type"
// 总分数
TotalScore float64 form:"total_score" json:"total_score,omitempty" xml:"total_score"
}

// CpResponse格式
type CpResponse struct {
// 重复项数量
Count int json:"count"
// 要显示的重复广告
Duplicated []DuplicatedAd json:"duplicated"
}

我定义了一个变量var DuplicatedAds = CpResponse{},并在循环中按照以下方式将一些结果追加到其中:

DuplicatedAds.Duplicated = append(DuplicatedAds.Duplicated, t)
DuplicatedAds.Count = len(DuplicatedAds.Duplicated)

我希望DuplicatedAds.Duplicated按照TotalScore进行排序。

我是Go语言的新手,所以经过一番研究,我发现在进行排序之前必须实现以下三个函数:

func (slice DuplicatedAd) Len() int {
return len(slice)
}

func (slice DuplicatedAd) Less(i, j int) bool {
return slice[i].TotalScore < slice[j].TotalScore
}

func (slice DuplicatedAd) Swap(i, j int) {
slice[i], slice[j] = slice[j], slice[i]
}

但是当我尝试编译时,我得到了以下错误:

./duplicates.go:165: cannot use DuplicatedAds.Duplicated (type []DuplicatedAd) as type sort.Interface in argument to sort.Sort:
[]DuplicatedAd does not implement sort.Interface (missing Len method)
./types.go:68: invalid argument slice (type DuplicatedAd) for len
./types.go:72: invalid operation: slice[i] (type DuplicatedAd does not support indexing)
./types.go:72: invalid operation: slice[j] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[i] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[j] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[i] (type DuplicatedAd does not support indexing)

如何使CpResponse对象的Duplicated数组按照DuplicatedAd.TotalScore排序?

英文:

I have two structs defined as below:

// DuplicatedAd format
type DuplicatedAd struct {
	// Ad Identifier
	AdID int `form:&quot;ad_id&quot; json:&quot;ad_id,omitempty&quot; xml:&quot;ad_id&quot;`
	// Parameters of an Ad, can be empty
	AdParams string `form:&quot;ad_params&quot; json:&quot;ad_params,omitempty&quot; xml:&quot;ad_params&quot;`
	// Body of the Ad
	Body string `form:&quot;body&quot; json:&quot;body,omitempty&quot; xml:&quot;body&quot;`
	// Body Duplicate Percentage
	BodyScore float64 `form:&quot;body_score&quot; json:&quot;body_score,omitempty&quot; xml:&quot;body_score&quot;`
	// Category of the Ad
	Category int `form:&quot;category&quot; json:&quot;category,omitempty&quot; xml:&quot;category&quot;`
	// The ad uploaded main image
	Image string `form:&quot;image,omitempty&quot; json:&quot;image,omitempty&quot; xml:&quot;image,omitempty&quot;`
	// Ad Listing ID
	ListID int `form:&quot;list_id&quot; json:&quot;list_id,omitempty&quot; xml:&quot;list_id&quot;`
	// Listing time for the ad
	ListTime string `form:&quot;list_time&quot; json:&quot;list_time,omitempty&quot; xml:&quot;list_time&quot;`
	// the ad Phone number
	Phone string `form:&quot;phone,omitempty&quot; json:&quot;phone,omitempty&quot; xml:&quot;phone,omitempty&quot;`
	// Region of the Ad
	Region int `form:&quot;region&quot; json:&quot;region,omitempty&quot; xml:&quot;region&quot;`
	// Ad Status
	Status string `form:&quot;status&quot; json:&quot;status,omitempty&quot; xml:&quot;status&quot;`
	// Subject of the Ad
	Subject string `form:&quot;subject&quot; json:&quot;subject,omitempty&quot; xml:&quot;subject&quot;`
	// Subject Duplicate Percentage
	SubjectScore float64 `form:&quot;subject_score&quot; json:&quot;subject_score,omitempty&quot; xml:&quot;subject_score&quot;`
	// Type of the Ad
	Type string `form:&quot;type&quot; json:&quot;type,omitempty&quot; xml:&quot;type&quot;`
	// Total Score
	TotalScore float64 `form:&quot;total_score&quot; json:&quot;total_score,omitempty&quot; xml:&quot;total_score&quot;`
}

// CpResponse format
type CpResponse struct {
	// Number of doublets
	Count int `json:&quot;count&quot;`
	// The Doublet Ads to show
	Duplicated []DuplicatedAd `json:&quot;duplicated&quot;`
}

i'm defining a variable var DuplicatedAds = CpResponse{}and in a loop i'm appending some results to it as follow:

DuplicatedAds.Duplicated = append(DuplicatedAds.Duplicated, t)
DuplicatedAds.Count = len(DuplicatedAds.Duplicated)

i wish that the DuplicatedAds.Duplicated be sorted by TotalScore.

i'm new to golang, so after a little research i found out that i must implement theses three functions before i can sort

func (slice DuplicatedAd) Len() int {
	return len(slice)
}

func (slice DuplicatedAd) Less(i, j int) bool {
	return slice[i].TotalScore &lt; slice[j].TotalScore
}

func (slice DuplicatedAd) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

but when i try to compile i get this errors:

./duplicates.go:165: cannot use DuplicatedAds.Duplicated (type []DuplicatedAd) as type sort.Interface in argument to sort.Sort:
	[]DuplicatedAd does not implement sort.Interface (missing Len method)
./types.go:68: invalid argument slice (type DuplicatedAd) for len
./types.go:72: invalid operation: slice[i] (type DuplicatedAd does not support indexing)
./types.go:72: invalid operation: slice[j] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[i] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[j] (type DuplicatedAd does not support indexing)
./types.go:76: invalid operation: slice[i] (type DuplicatedAd does not support indexing)

How could i have an CpResponse object which his Duplicated array is sorted by DuplicatedAd.TotalScore ?

答案1

得分: 5

从Go 1.8开始,您可以使用以下函数对切片进行排序:

sort.Slice(DuplicatedAds.Duplicated, func(i int, j int) bool {
    return DuplicatedAds.Duplicated[i].TotalScore < DuplicatedAds.Duplicated[j].TotalScore
})

您不再需要在上面定义那三个函数(LenLessSwap)。请注意,我们在sort.Slice的参数中使用了相同的Len实现。

英文:

Starting from Go 1.8, you can use the following function to sort your slice:

sort.Slice(DuplicatedAds.Duplicated, func(i int, j int) bool {
    return DuplicatedAds.Duplicated[i].TotalScore &lt; DuplicatedAds.Duplicated[j].TotalScore
})

You don't need to define those three functions up there anymore (Len, Less and Swap). Notice how we used the same implementation of Len as a parameter of sort.Slice.

答案2

得分: 0

cd1提供了一个很好的解决方案。至于你的方法不起作用的原因,是因为它们操作的是单个结构体而不是结构体切片。

你需要像这样对每个方法进行修改,使其作用于DuplicatedAdSlice类型而不是DuplicatedAd类型。

type DuplicatedAdSlice []DuplicatedAd // 类型别名

func (slice DuplicatedAdSlice) Len() int {
    return len(slice)
}

并且更新CpResponse结构体以使用类型别名

// 要显示的重复广告
Duplicated DuplicatedAdSlice `json:"duplicated"`
英文:

cd1 offers a good solution. As for the reason your methods aren't working, it's because they're operating on a single struct and not a slice of structs.

You would want something more like this where each method works on the DuplicatedAdSlice type rather than the DuplicatedAd type.

type DuplicatedAdSlice []DuplicatedAd // Type alias

func (slice DuplicatedAdSlice) Len() int {
    return len(slice)
}

And update the CpResponse struct to use the type alias

// The Doublet Ads to show
Duplicated DuplicatedAdSlice `json:&quot;duplicated&quot;`

huangapple
  • 本文由 发表于 2017年3月29日 18:25:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/43090918.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定