当前位置: 首页 > 知识库问答 >
问题:

按(任意)字段名对结构数组进行简单排序的最短方法是什么?

严景焕
2023-03-14

我只是有一个问题,我有一个数组的结构,例如。

package main

import "log"

type Planet struct {
    Name       string  `json:"name"`
    Aphelion   float64 `json:"aphelion"`   // in million km
    Perihelion float64 `json:"perihelion"` // in million km
    Axis       int64   `json:"Axis"`       // in km
    Radius     float64 `json:"radius"`
}

func main() {
    var mars = new(Planet)
    mars.Name = "Mars"
    mars.Aphelion = 249.2
    mars.Perihelion = 206.7
    mars.Axis = 227939100
    mars.Radius = 3389.5

    var earth = new(Planet)
    earth.Name = "Earth"
    earth.Aphelion = 151.930
    earth.Perihelion = 147.095
    earth.Axis = 149598261
    earth.Radius = 6371.0

    var venus = new(Planet)
    venus.Name = "Venus"
    venus.Aphelion = 108.939
    venus.Perihelion = 107.477
    venus.Axis = 108208000
    venus.Radius = 6051.8

    planets := [...]Planet{*mars, *venus, *earth}
    log.Println(planets)
}

假设您想按轴对其进行排序。你是怎么做到的?

(注:我看过http://golang.org/pkg/sort/,好像还能用,但光靠一个很简单的按键简单排序,就得加20行左右。我有一个Python背景,它是简单的排序(行星,key=lambda n: n。轴)-有类似的简单围棋吗?(


共有3个答案

越骏俊
2023-03-14

截至Go 1.8,@AndreKR的答案是更好的解决方案。

您可以实现实现排序接口的集合类型。

下面是两种类型的示例,允许您按轴或名称进行排序

package main

import "log"
import "sort"

// AxisSorter sorts planets by axis.
type AxisSorter []Planet

func (a AxisSorter) Len() int           { return len(a) }
func (a AxisSorter) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a AxisSorter) Less(i, j int) bool { return a[i].Axis < a[j].Axis }

// NameSorter sorts planets by name.
type NameSorter []Planet

func (a NameSorter) Len() int           { return len(a) }
func (a NameSorter) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a NameSorter) Less(i, j int) bool { return a[i].Name < a[j].Name }

type Planet struct {
    Name       string  `json:"name"`
    Aphelion   float64 `json:"aphelion"`   // in million km
    Perihelion float64 `json:"perihelion"` // in million km
    Axis       int64   `json:"Axis"`       // in km
    Radius     float64 `json:"radius"`
}

func main() {
    var mars Planet
    mars.Name = "Mars"
    mars.Aphelion = 249.2
    mars.Perihelion = 206.7
    mars.Axis = 227939100
    mars.Radius = 3389.5

    var earth Planet
    earth.Name = "Earth"
    earth.Aphelion = 151.930
    earth.Perihelion = 147.095
    earth.Axis = 149598261
    earth.Radius = 6371.0

    var venus Planet
    venus.Name = "Venus"
    venus.Aphelion = 108.939
    venus.Perihelion = 107.477
    venus.Axis = 108208000
    venus.Radius = 6051.8

    planets := []Planet{mars, venus, earth}
    log.Println("unsorted:", planets)

    sort.Sort(AxisSorter(planets))
    log.Println("by axis:", planets)

    sort.Sort(NameSorter(planets))
    log.Println("by name:", planets)
}
龚国源
2023-03-14

更新:此答案与较旧版本的go有关。对于Go 1.8和更新版本,请参见上面AndreKR的答案。

如果您想要比标准库sortpackage更简洁的东西,可以使用第三方github。com/bradfitz/slice软件包。它使用一些技巧来生成排序切片所需的LenSwap方法,因此您只需要提供Less方法。

使用此软件包,您可以通过以下方式执行排序

slice.Sort(planets[:], func(i, j int) bool {
    return planets[i].Axis < planets[j].Axis
})

planets[:]部件是生成覆盖阵列的切片所必需的。如果你制作了一个切片而不是一个数组,你可以跳过这个部分。

蒋飞捷
2023-03-14

从Go 1.8开始,现在可以使用sort。切片对切片进行排序:

sort.Slice(planets, func(i, j int) bool {
  return planets[i].Axis < planets[j].Axis
})

通常没有理由使用数组而不是切片,但是在您的示例中,您使用的是数组,因此您必须用切片覆盖它(添加[:])以使其与排序一起工作。切片

sort.Slice(planets[:], func(i, j int) bool {
  return planets[i].Axis < planets[j].Axis
})

排序会更改数组,因此如果确实需要,可以在排序后继续使用数组而不是切片。

 类似资料:
  • 问题内容: 我只是有一个问题,我有一系列的结构,例如 假设您要按排序。你是怎样做的? (注意:我已经看过http://golang.org/pkg/sort/,并且似乎可以正常工作,但是为了通过一个非常简单的键进行简单排序,我必须添加大约20行。我在这里有python背景一样简单-Go中有类似的东西吗? 问题答案: 更新: 此答案与的旧版本有关。对于Go1.8及更高版本,请参见下面的AndreKR

  • 问题内容: 如何按其字段之一(例如或)对对象数组进行排序? 问题答案: 使用usort,这是从手册改编而成的示例: 您还可以将任何callable用作第二个参数。这里有些例子: 使用匿名函数(来自PHP 5.3) 从班级内部 使用箭头函数(来自PHP 7.4) 另外,如果要比较数字值,则应使用“比较”功能。

  • 问题内容: 我有这样的数组 如何按return_fare asc和one_way_fare asc排序值? 我尝试了array_multisort()但最终却得到了混乱的数据。 Asort仅适用于一维数组,我需要按两个或多个值进行排序,我如何才能像SQL中那样实现此功能,按field1 asc,field2 asc排序? 问题答案: 是正确的函数,您必须以某种方式搞砸了: 如果您在PHP的手册页上

  • 问题内容: 我得到了一个数组(请参阅下面的数组中的一个对象),我需要使用JavaScript按名字排序。我该怎么做? 问题答案: 假设您有一个数组。您可以使用并传递一个接受两个参数并进行比较的函数(比较器) 它应该返回 如果第一个参数小于第二个参数,则为负数(应在结果数组的第二个参数之前放置) 如果第一个参数较大,则为正数(应放在第二个参数之后) 如果这两个元素相等,则为0。 在我们的情况下,如果

  • 我需要按字段“priority”(定义为文本)对bucket进行排序,但我不知道该怎么做。 你介意帮我做这件事吗? 我尝试过bucket_sort,但ES给出了一个关于类型的错误,与sort和order相同。 这是聚合查询 结果示例如下: 我想按索引中定义为文本的字段“优先级”对存储桶聚合(asc/desc)进行排序

  • 问题内容: 因此,在数据库中,我存储了乐器名称(以及其他各种属性)。假设它是主键,并且是唯一键。 在PHP脚本中,我按其乐器类选择项,如下所示: 结果表: 这使我可以仅通过查询“萨克斯管”来选择整个乐器系列,例如“高音萨克斯管”,“中音萨克斯管”等。 在该特定示例中,结果按其ID排序(您可以假定其为auto_incremented)。更理想的是按字母顺序排序,是吗? 这工作正常,但作为音乐人,他们