golang排序片上升或下降

kgqe7b3p  于 2023-06-19  发布在  Go
关注(0)|答案(9)|浏览(143)

我需要对来自第三方软件包的类型进行排序。根据某些条件,顺序必须是升序或降序。
我想到的解决方案是:

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行代码,而且大部分都是重复的,似乎有点太多了。

sd2nnvve

sd2nnvve1#

从Go 1.8开始,有一种更简单的方法来对切片进行排序,不需要定义新类型。只需将一个匿名函数传递给sort.Slice函数。

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)
}

这将按升序排序,如果你想要相反的,只需在匿名函数中写入a[i] > a[j]

ygya80vv

ygya80vv2#

你在找sort.Reverse这会让你说:

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

gmol16393#

我下面的答案是基于这样的假设,即您从第三方包接收的切片是基本的Go类型。
要对基本类型的片进行排序,请使用排序包实用程序。下面是一个对string和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类型进行排序不需要实现像Len()这样属于sort.Interface的函数。您只需要对复合类型采用这种方法。
1.只需使用适当的Interface方法提供程序 Package 基本类型的类型,例如StringSlice、IntSlice或Float64Slice,并进行排序。
1.切片是就地排序的,因此不会返回已排序切片的副本。

kxe2p93d

kxe2p93d4#

公认的答案是好的,但我不同意他们关于下降的建议:

a[i] > a[j]

对于sort.Slice,提供的函数应该表示“小于”的实现:
func Slice(x interface{}, less func(i, j int) bool)
Slice根据提供的less函数对切片x进行排序。如果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

qmelpv7a

qmelpv7a5#

也许你可以使用sort.Sort方法来排序切片。:)

func TestSorted(t *testing.T) {
    nums := []int{4, 3, 2, 3, 5, 2, 1}
    // descending
    sort.Sort(sort.Reverse(sort.IntSlice(nums)))
    fmt.Println(nums) // [5 4 3 3 2 2 1]
    // ascending
    sort.Sort(sort.IntSlice(nums))
    fmt.Println(nums) // [1 2 2 3 3 4 5]
}
y53ybaqx

y53ybaqx6#

你可以从golang的标准库中导入“sort”包。然后你可以使用“Slice”或“SliceStable”函数来排序你的切片。建议使用第二个,如下所示:

sort.SliceStable(yourSlice , anonnymousFunction)

示例:包main

import (
    "fmt"
    "sort"
)
func main() {
    a := []int{4,5,9,6,8,3,5,7,99,58,1}
    sort.SliceStable(a, func(i,j int )bool{
        //i,j are represented for two value of the slice .
        return a[i] < a[j]
    })
    fmt.Println(a)
}
a1o7rhls

a1o7rhls7#

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

xxb16uws

xxb16uws8#

升序排序:
package main

import (
    "fmt"
    "sort"
)

func main() {
    // unsorted string and integer slices
    strData := []string{"Go", "Bravo", "Gopher", "Alpha", "Grin", "Delta"}
    intData := []int{5, 2, 6, 3, 1, 4}

    // sort in-place in ascending order
    sort.Ints(intData)
    sort.Strings(strData)

    // print
    fmt.Println(intData)
    fmt.Println(strData)
}

输出:

[Alpha Bravo Delta Go Gopher Grin]
[1 2 3 4 5 6]
降序排序:
package main

import (
    "fmt"
    "sort"
)

func main() {
    // unsorted int and string slices
    strData := []string{"Go", "Bravo", "Gopher", "Alpha", "Grin", "Delta"}
    intData := []int{5, 2, 6, 3, 1, 4}

    // sort in-place in descending order
    sort.Sort(sort.Reverse(sort.IntSlice(intData)))
    sort.Sort(sort.Reverse(sort.StringSlice(strData)))

    // print
    fmt.Println(intData)
    fmt.Println(strData)
}

输出:

[6 5 4 3 2 1]
[Grin Gopher Go Delta Bravo Alpha]
zzwlnbp8

zzwlnbp89#

如果由于任何原因你不能或不想使用sort包,下面将实现一个冒泡排序类型的排序(它接受一个int64切片并返回一个int64切片):

func sortSlice ( S []int64 ) []int64 {
  // sort using bubblesort, comparing each pairs of numbers and ensuring that left is lower than right
  for i := len(S); i > 0 ; i-- {
    for j := 1; j < i; j++ {
      if S[j-1] > S[j] {
        // swap
        intermediate := S[j]
        S[j] = S[j-1]
        S[j-1] = intermediate
      }
    }
  }
  return S
}

相关问题