在 Go 中组合不同的排序
如何在 Go 中组合排序器?例如,首先我需要按评论数量排序,但如果评论数量为空,我需要按字母顺序排序。
这是我尝试过的。
func sortArticles(articles []*Article) []*Article {
topArticlesSlice := make([]*Article, 0)
topArticlesSlice = append(topArticlesSlice, articles[:]...)
sort.SliceStable(topArticlesSlice, func(i, j int) bool {
var sortedByNumComments, areNumCommentsEquals, sortedByName bool
if topArticlesSlice[i].NumComments != nil && topArticlesSlice[j].NumComments != nil {
areNumCommentsEquals = *topArticlesSlice[i].NumComments == *topArticlesSlice[j].NumComments
sortedByNumComments = *topArticlesSlice[i].NumComments > *topArticlesSlice[j].NumComments
}
if areNumCommentsEquals {
if topArticlesSlice[i].Title != nil && topArticlesSlice[j].Title != nil {
sortedByName = *topArticlesSlice[i].Title == *topArticlesSlice[j].Title
return sortedByName
} else if topArticlesSlice[i].StoryTitle != nil && topArticlesSlice[j].StoryTitle != nil {
sortedByName = *topArticlesSlice[i].StoryTitle == *topArticlesSlice[j].StoryTitle
return sortedByName
}
return false
}
return sortedByNumComments
})
return topArticlesSlice
}
我的结构(https://go.dev/play/p/27j-sFKaG2M )
type ArticleResponse struct {
Page int `json:"page"`
PerPage int `json:"per_page"`
Total int `json:"total"`
TotalPages int `json:"total_pages"`
Articles []*Article `json:"data"`
}
type Article struct {
Title *string `json:"title"`
URL *string `json:"url"`
Author string `json:"author"`
NumComments *int `json:"num_comments"`
StoryID interface{} `json:"story_id"`
StoryTitle *string `json:"story_title"`
StoryURL *string `json:"story_url"`
ParentID *int `json:"parent_id"`
CreatedAt int `json:"created_at"`
}
How can I combine sorters in Go? For example first I need sort by number of comments but if number of comments is null I need sort alphabetically.
This is what I have tried.
func sortArticles(articles []*Article) []*Article {
topArticlesSlice := make([]*Article, 0)
topArticlesSlice = append(topArticlesSlice, articles[:]...)
sort.SliceStable(topArticlesSlice, func(i, j int) bool {
var sortedByNumComments, areNumCommentsEquals, sortedByName bool
if topArticlesSlice[i].NumComments != nil && topArticlesSlice[j].NumComments != nil {
areNumCommentsEquals = *topArticlesSlice[i].NumComments == *topArticlesSlice[j].NumComments
sortedByNumComments = *topArticlesSlice[i].NumComments > *topArticlesSlice[j].NumComments
}
if areNumCommentsEquals {
if topArticlesSlice[i].Title != nil && topArticlesSlice[j].Title != nil {
sortedByName = *topArticlesSlice[i].Title == *topArticlesSlice[j].Title
return sortedByName
} else if topArticlesSlice[i].StoryTitle != nil && topArticlesSlice[j].StoryTitle != nil {
sortedByName = *topArticlesSlice[i].StoryTitle == *topArticlesSlice[j].StoryTitle
return sortedByName
}
return false
}
return sortedByNumComments
})
return topArticlesSlice
}
My structs (https://go.dev/play/p/27j-sFKaG2M)
type ArticleResponse struct {
Page int `json:"page"`
PerPage int `json:"per_page"`
Total int `json:"total"`
TotalPages int `json:"total_pages"`
Articles []*Article `json:"data"`
}
type Article struct {
Title *string `json:"title"`
URL *string `json:"url"`
Author string `json:"author"`
NumComments *int `json:"num_comments"`
StoryID interface{} `json:"story_id"`
StoryTitle *string `json:"story_title"`
StoryURL *string `json:"story_url"`
ParentID *int `json:"parent_id"`
CreatedAt int `json:"created_at"`
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的比较功能太复杂了。您需要将其重构为更简单、更直接的部分。
而且,您还没有定义您的
Article
类型,因此,出于示例的目的,我将这样定义它:您的基本要求是您想要排序,首先按评论数,然后(如果评论数为零)按标题字母顺序排列,对吗?
从您的原始代码来看,
NumComments
是一个指向 int (*int
) 的指针,Title
是一个指向字符串 (< code>*string)这意味着每次比较都有四种种情况需要处理:
出于本练习的目的,我将声明 nil 相对于非 nil 进行高整理(但 nil 相对于非 nil 进行低整理是同样有效的实施选择)。
比较 2 个
*int
值很简单:就像比较两个
*string
值一样:有了这些基元后,用于排序的比较器函数就更简单了:
Your compare function is far too complex. You need to refactor it into simpler more straightforward bits.
And, you haven't defined what your
Article
type looks like, so, for the purposes of example, I'm going to define it thus:Your basic ask is that you want to sort, first by the number of comments, and then (if the number of comments is nil) alphabetically by title, correct?
From your original code, it would appear that
NumComments
is a pointer to int (*int
), andTitle
is a pointer to string (*string
)That means that each comparison has four cases that have to be dealt with:
For the purposes of this exercise, I'm going to declare that nil collates high with respect to non-nil (but nil collating low with respect to non-nil is equally valid. An implementation choice).
Comparing 2
*int
values is easy:As is comparing two
*string
values:Once you have those primitives, the comparer function for the sort is even simpler:
您的帖子中缺少一些类型定义。我举了一个简单的支柱示例。我想这就是您可能正在寻找的?
Some of the type definitions are missing in your post. I have taken a simple strut example. I think this is what you may be looking for?
假设我正确理解您的要求,您可以使用类似以下内容:
在 游乐场。
Assuming I'm understanding your requirement correctly you can use something like the following:
Try this in the playground.