我有一个Points类型的多维点列表.
我已经实现了sort.Sort
界面,现在可以排序了y value
.
例如
type Points []*Point
func (points Points) Len() int {
return len(points)
}
func (points Points) Less(i, j int) bool {
return points[i].y < points[j].y
}
func (points Points) Swap(i, j int) {
points[i], points[j] = points[j], points[i]
}
type Point struct {
x int
y int
country_id int
}
Run Code Online (Sandbox Code Playgroud)
现在我想用x value
而不是来分类我的观点y value
.
我的想法是使用带有全局标志的if语句(可以在排序之前打开或关闭):
func (points Points) Less(i, j int) bool {
if SORT_BY_X {
return points[i].x < points[j].x
}
return points[i].y < points[j].y
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法呢?我应该多次实施Less吗?如果我按列排序数据表怎么办?
啊,这很有趣:sort.Sort()
期望类型定义一个排序和一些数组操作.你可以拥有"X-sortable point list"和"Y-sortable point list"类型,但是让它们共享数组ops与其他语言的工作方式不同,因为Go不使用继承.
我想到的第一个办法是创建XSortablePoints
和YSortablePoints
每个独立实现类型sort.Interface
,和你的转换Points
实例,你需要哪一个的时刻-在这里看到:http://play.golang.org/p/9V3WlKjOwX.
然后nemo有一个更好的方法:类型嵌入允许XSortablePoints
和YSortablePoints
共享数组操作的函数.此外,nemo不会将可排序类型保存在变量中,这是有意义的,因为它们仅存在于此一个排序调用中.这是经过调整的示例代码:http://play.golang.org/p/wNm-ilM18n
请注意,这两种方法都不会在您投射时实际复制您的点数据,只是切片标题.您可以通过查看第一个示例打印出的指针地址来查看.
你可以得到更好的:有一个Points.Sort在http://play.golang.org/p/4PmJVi2_7D上进行任意比较功能.我认为只要定义更多类型的蛮力方法就可以,只要您只有两个或三个排序,但情况会有所不同.请注意,对于比这里的点大得多的类型,您可能希望将比较器定义为使用指针而不是值,以避免复制.
re :: SORT_BY_X
我通常会避免在程序运行时更新的全局模式设置变量,因为有很多方法可以回过头来咬你.例如,也许你有一天会有两个并行的goroutine,然后当它们同时访问全局时会出现问题.或者也许某些代码在SORT_BY_X的初始值为时会起作用false
,然后有一天会失败,因为它是true
在另一个任务运行后留下的.如果您确实发现自己需要模式变量,请确定是否可以将其作为函数参数或将其附加到对象,而不是它是全局变量.
最后,可能有一个软件包已经提供了您想要的一些更高级别的功能.例如,有一些与此处列出的地理数据相关的软件包:https://code.google.com/p/go-wiki/wiki/Projects#GIS
除了user2714852的答案之外,您还可以使用与已经用于在sort
包中反转排序相同的技术:遮蔽Less()
定义.
虽然这与已经提出的相似,但到达那里的方式有点不同(例如在游戏中).你定义你的要点:
type Points []Point
func (points Points) Swap(i, j int) {
points[i], points[j] = points[j], points[i]
}
func (points Points) Len() int {
return len(points)
}
Run Code Online (Sandbox Code Playgroud)
对于每种排序方法,您实现自己的类型,嵌入您的Points
类型:
type XPoints struct {
Points
}
func (points XPoints) Less(i,j int) bool {
return points.Points[i].x < points.Points[j].x
}
type YPoints struct {
Points
}
func (points YPoints) Less(i, j int) bool {
return points.Points[i].y < points.Points[j].y
}
Run Code Online (Sandbox Code Playgroud)
现在您可以使用不同的排序方法,如下所示:
pts := Points{{1, 2, 3}, {2, 1, 3}}
sort.Sort(XPoints{pts})
fmt.Println("X-sorted points:", pts)
sort.Sort(YPoints{pts})
fmt.Println("Y-sorted points:", pts)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1869 次 |
最近记录: |