web-dev-qa-db-ja.com

golang sort slice昇順または降順

サードパーティのパッケージに由来するタイプのスライスをソートする必要があります。何らかの条件に基づいて、順序は昇順または降順でなければなりません。

私が思いついた解決策は次のとおりです。

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行のコードとそのほとんどが重複しているため、少し多すぎるようです。

11
gsf

Go 1.8では、新しいタイプを定義する必要のないスライスを簡単にソートする方法があります。単純にLess(匿名)ラムダを作成します。

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]ラムダ。

32
Franck Jeannin

あなたが探しています - sort.Reverse 。それはあなたに言うことができます:

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

以下の私の答えは、サードパーティのパッケージから受け取っているスライスが基本的な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. 適切なインターフェイスメソッドプロバイダーを使用して、基本型の型をラップするだけです。 StringSliceIntSlice 、または Float64Slice 、および並べ替え。

  3. スライスはインプレースでソートされるため、ソートされたスライスのコピーは返されません。

5
user1820956