按通过原型消息定义的日期对 GO 结构进行排序
sorting a GO struct by date which is defined via proto message
我在原型文件中定义了一条消息:
my.proto
--------
message Holiday {
string title = 1;
google.protobuf.Timestamp date = 2;
}
编译后创建my.pb.go
现在在我的 go 代码中,我有一段假期。
main.go
-------
holidays := []my.Holiday{...}
我必须按 Holiday.date 对这个切片进行排序。根据文档,如果我想使用 sort.Sort 进行排序,那么我必须实现 Len、Swap & Less 方法。但是我不能在我的 go 代码中定义这些接收器方法,因为 Holiday
来自不同的包 (my.pb.go)。
有什么办法可以解决这个问题吗?
谢谢,
您可以只使用 sort.Slice
,不需要实施 sort.Interface
。
Slice sorts the slice x given the provided less function. It panics if x is not a slice.
sort.Slice(holidays, func(i, j int) bool {
return holidays[i].GetDate().Before(holidays[j].GetDate())
})
SortKeys
示例 in the sort.Sort documentation 显示了如何使用临时结构来完成此操作:
// A Planet defines the properties of a solar system object.
type Planet struct {
name string
mass earthMass
distance au
}
// By is the type of a "less" function that defines the ordering of its Planet arguments.
type By func(p1, p2 *Planet) bool
// Sort is a method on the function type, By, that sorts the argument slice according to the function.
func (by By) Sort(planets []Planet) {
ps := &planetSorter{
planets: planets,
by: by, // The Sort method's receiver is the function (closure) that defines the sort order.
}
sort.Sort(ps)
}
// planetSorter joins a By function and a slice of Planets to be sorted.
type planetSorter struct {
planets []Planet
by func(p1, p2 *Planet) bool // Closure used in the Less method.
}
// Len is part of sort.Interface.
func (s *planetSorter) Len() int {
return len(s.planets)
}
// Swap is part of sort.Interface.
func (s *planetSorter) Swap(i, j int) {
s.planets[i], s.planets[j] = s.planets[j], s.planets[i]
}
// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
func (s *planetSorter) Less(i, j int) bool {
return s.by(&s.planets[i], &s.planets[j])
}
鉴于 sort.Sort
只需要一个 sort.Interface
,它不关心你使用的是什么数据结构或者你实际交换的是什么类型。
sort package documentation 显示了回答问题的两个示例。
first package example 使用所需方法声明切片类型:
type Person struct {
Name string
Age int
}
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
...
sort.Sort(ByAge(people))
请注意,Len、Swap 和 Less 方法是在为排序定义的切片类型上,而不是在结构类型上。您可以在自己的包中定义该类型。
sort.Slice example 显示了如何仅使用 less 函数进行排序:
sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
在此示例中,无需为排序目的定义类型。
我在原型文件中定义了一条消息:
my.proto
--------
message Holiday {
string title = 1;
google.protobuf.Timestamp date = 2;
}
编译后创建my.pb.go
现在在我的 go 代码中,我有一段假期。
main.go
-------
holidays := []my.Holiday{...}
我必须按 Holiday.date 对这个切片进行排序。根据文档,如果我想使用 sort.Sort 进行排序,那么我必须实现 Len、Swap & Less 方法。但是我不能在我的 go 代码中定义这些接收器方法,因为 Holiday
来自不同的包 (my.pb.go)。
有什么办法可以解决这个问题吗?
谢谢,
您可以只使用 sort.Slice
,不需要实施 sort.Interface
。
Slice sorts the slice x given the provided less function. It panics if x is not a slice.
sort.Slice(holidays, func(i, j int) bool {
return holidays[i].GetDate().Before(holidays[j].GetDate())
})
SortKeys
示例 in the sort.Sort documentation 显示了如何使用临时结构来完成此操作:
// A Planet defines the properties of a solar system object.
type Planet struct {
name string
mass earthMass
distance au
}
// By is the type of a "less" function that defines the ordering of its Planet arguments.
type By func(p1, p2 *Planet) bool
// Sort is a method on the function type, By, that sorts the argument slice according to the function.
func (by By) Sort(planets []Planet) {
ps := &planetSorter{
planets: planets,
by: by, // The Sort method's receiver is the function (closure) that defines the sort order.
}
sort.Sort(ps)
}
// planetSorter joins a By function and a slice of Planets to be sorted.
type planetSorter struct {
planets []Planet
by func(p1, p2 *Planet) bool // Closure used in the Less method.
}
// Len is part of sort.Interface.
func (s *planetSorter) Len() int {
return len(s.planets)
}
// Swap is part of sort.Interface.
func (s *planetSorter) Swap(i, j int) {
s.planets[i], s.planets[j] = s.planets[j], s.planets[i]
}
// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
func (s *planetSorter) Less(i, j int) bool {
return s.by(&s.planets[i], &s.planets[j])
}
鉴于 sort.Sort
只需要一个 sort.Interface
,它不关心你使用的是什么数据结构或者你实际交换的是什么类型。
sort package documentation 显示了回答问题的两个示例。
first package example 使用所需方法声明切片类型:
type Person struct {
Name string
Age int
}
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
...
sort.Sort(ByAge(people))
请注意,Len、Swap 和 Less 方法是在为排序定义的切片类型上,而不是在结构类型上。您可以在自己的包中定义该类型。
sort.Slice example 显示了如何仅使用 less 函数进行排序:
sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
在此示例中,无需为排序目的定义类型。