golang排序切片升序或降序

时间:2016-06-08 06:51:41

标签: sorting go

我需要对来自3rdparty包的类型进行排序。根据某些条件,订单必须是升序或降序。

我提出的解决方案是:

type fooAscending []foo

func (v fooAscending) Len() int           { return len(v) }
func (v fooAscending) Swap(i, j int)      { v[i], v[j] = v[j], v[i] }
func (v fooAscending) Less(i, j int) bool { return v[i].Amount < v[j].Amount }

type fooDescending []foo

func (v fooDescending) Len() int           { return len(v) }
func (v fooDescending) Swap(i, j int)      { v[i], v[j] = v[j], v[i] }
func (v fooDescending) Less(i, j int) bool { return v[i].Amount > v[j].Amount }

if someCondition {
    sort.Sort(fooAscending(array))
} else {
    sort.Sort(fooDescending(array))
}

有没有更好的方法来做到这一点。这项任务的13行代码,其中大部分是重复的,似乎有点太多了。

5 个答案:

答案 0 :(得分:25)

从Go 1.8开始,有一种更简单的方法可以对切片进行排序,而不需要您定义新类型。您只需创建一个Less(匿名)lambda。

a := []int{5, 3, 4, 7, 8, 9}
sort.Slice(a, func(i, j int) bool {
    return a[i] < a[j]
})
for _, v := range a {
    fmt.Println(v)
}

这将按升序排序,如果您想要相反,只需在lambda中写a[i] > a[j]

答案 1 :(得分:9)

您正在寻找sort.Reverse。那会让你说:

sort.Sort(sort.Reverse(fooAscending(s)))

答案 2 :(得分:4)

我在下面的回答是基于这样的假设,即您从第三方软件包收到的切片是基本的Go类型。

要对基本类型的切片进行排序,请使用排序包实用程序。下面是一个对字符串切片和int切片进行排序的示例。

package main

import (
    "fmt"
    "sort"
)

func main() {
    sl := []string{"mumbai", "london", "tokyo", "seattle"}
    sort.Sort(sort.StringSlice(sl))
    fmt.Println(sl)

    intSlice := []int{3,5,6,4,2,293,-34}
    sort.Sort(sort.IntSlice(intSlice))
    fmt.Println(intSlice)
}

以上的输出是:

[london mumbai seattle tokyo]
[-34 2 3 4 5 6 293]

转到Go Playground here自行试用。

注意事项:

  1. 对基本Go类型进行排序不需要实现属于sort.Interface的Len()等函数。您只需要为复合类型采用该路由。

  2. 使用适当的接口方法提供程序包装基本类型的类型,例如StringSliceIntSliceFloat64Slice,并排序。

  3. 切片就地排序,因此不会返回已排序切片的副本。

答案 3 :(得分:0)

`var names = []string{"b", "a", "e", "c", "d"}
    sort.Strings(names)
    fmt.Println("Sorted in alphabetical order", names)
    sort.Sort(sort.Reverse(sort.StringSlice(names)))
    fmt.Println("Sorted in reverse order", names)`

The Go Playgound https://play.golang.org/p/Q8KY_JE__kx的链接

答案 4 :(得分:0)

接受的答案很好,但我不同意他们关于降序的建议:

a[i] > a[j]

使用 sort.Slice,提供的函数应该代表一个 “小于”的实现:

<块引用>

func Slice(x interface{}, less func(i, j int) bool)

Slice 根据提供的 x 函数对切片 less 进行排序。如果它恐慌 x 不是切片。

所以写一个“大于”函数,对给定的描述并不真实。 最好是反转索引:

package main

import (
   "fmt"
   "sort"
)

func main() {
   a := []int{5, 3, 4, 7, 8, 9}
   sort.Slice(a, func(i, j int) bool {
      return a[j] < a[i]
   })
   fmt.Println(a) // [9 8 7 5 4 3]
}

两者都应该返回相同的结果,但我认为一个更惯用。

https://golang.org/pkg/sort#Slice