在Go中对一个片断进行反向排序的教程

1,194 阅读2分钟

在Go中,如果你有一个简单类型的片断,如[]int,[]string, 或[]float64 ,你可以用 sort.Ints(), sort.Strings(),或 sort.Float64s()函数进行排序。但是,它们只能对切片进行升序排序。要以降序排序,你必须使用更通用的函数 sort.Sort()和数据反转函数 sort.Reverse().

package main

import (
    "fmt"
    "sort"
)

func main() {
    numbers := []int{4, 3, 2, 1, 0, 4, 7, 5}
    // sort ints ascending
    sort.Ints(numbers)
    fmt.Println(numbers)

    // sort ints descending
    sort.Sort(sort.Reverse(sort.IntSlice(numbers)))
    fmt.Println(numbers)

    // sort strings descending
    chars := []string{"a", "b", "c"}
    sort.Sort(sort.Reverse(sort.StringSlice(chars)))
    fmt.Println(chars)
}

输出。

[0 1 2 3 4 4 5 7]
[7 5 4 4 3 2 1 0]
[c b a]

看一下这个例子。要对一个[]int slice进行降序排序,你需要:

  1. []int slice转换为 sort.IntSlice,这使得该片成为一个接口的实例。 sort.Interface接口。
  2. 将包含在界面中的元素的标准升序颠倒过来。 sort.IntSlice中的元素的标准升序。 sort.Reverse()函数来反转其中的元素。
  3. 使用一般的 sort.Sort()函数对反转的片断进行排序。

同样的方案适用于对[]string[]float64 列表进行排序,但必须将其转换为 sort.StringSlicesort.Float64Slice.

在使用数据反转函数时,没有内置的选项来反转顺序。 sort.Slice()和一个自定义的排序函数less 时,没有内置的选项来反转顺序。然而,我们可以自己做。在下面的例子中,reverse() 函数 "反转 "了less 函数。这样,我们就可以创建一个单一的less 函数来对结构片进行排序,然后根据参数或用例以升序或降序进行排序。

package main

import (
    "fmt"
    "sort"
)

type Fruit struct {
    Name  string
    Color string
    Rank  int
}

func reverse(less func(i, j int) bool) func(i, j int) bool {
    return func(i, j int) bool {
        return !less(i, j)
    }
}

func main() {
    fruits := []Fruit{
        {
            Name:  "Strawberry",
            Color: "red",
            Rank:  2,
        },
        {
            Name:  "Raspberry",
            Color: "pink",
            Rank:  1,
        },
        {
            Name:  "Banana",
            Color: "yellow",
            Rank:  3,
        },
    }

    less := func(i, j int) bool {
        return fruits[i].Rank < fruits[j].Rank
    }

    // sort structs ascending
    sort.Slice(fruits, less)
    fmt.Println(fruits)

    // sort structs descending
    sort.Slice(fruits, reverse(less))
    fmt.Println(fruits)
}

输出

[{Raspberry pink 1} {Strawberry red 2} {Banana yellow 3}]
[{Banana yellow 3} {Strawberry red 2} {Raspberry pink 1}]