【golang】sortパッケージの使い方

Golangの標準パッケージである「sort」は、スライスの要素をソートするための便利な機能を提供します。このパッケージを使用すると、異なるデータ型のスライスをソートできます。

スライスのソート方法

Golangの「sort」パッケージは、sort.Slice()メソッドを使用してスライスをソートします。このメソッドには、3つの引数があります。

sort.Slice(slice []T, less func(i, j int) bool)
  • slice:ソートするスライス
  • less:スライスの2つの要素を比較するための関数

less関数は、スライスの要素を比較するために使用されます。関数の戻り値がtrueの場合、スライスの要素は交換されます。falseの場合、スライスの要素はそのままになります。

以下は、整数型のスライスをソートする例です。

package main

import (
    "fmt"
    "sort"
)

func main() {
    slice := []int{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}

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

    fmt.Println(slice)
}

この例では、sort.Slice()メソッドを使用して整数型のスライスをソートしています。less関数は、sliceの2つの要素を比較し、左側の要素が右側の要素より小さい場合にtrueを返します。

ソートの順序の変更

スライスを昇順でソートするには、less関数で左側の要素が右側の要素より小さい場合にtrueを返します。降順でソートするには、less関数で左側の要素が右側の要素より大きい場合にtrueを返します。以下は、降順でソートする例です。

package main

import (
    "fmt"
    "sort"
)

func main() {
    slice := []int{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}

    sort.Slice(slice, func(i, j int) bool {
        return slice[i] > slice[j]
    })

    fmt.Println(slice)
}

この例では、less関数がslice[i] > slice[j]で定義されています。これにより、スライスの要素が降順でソートされます。

カスタム型のスライスのソート

Golangの「sort」パッケージを使用すると、カスタム型のスライスをソートできます。カスタム型のスライスをソートするには、less関数をカスタム型に合わせて定義する必要があります。

以下は、カスタム型のスライスをソートする例です。

package main

import (
    "fmt"
    "sort"
)

type Person struct {
    Name string
    Age  int
}

type ByAge []Person

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

func main() {
    people := []Person{
        {"Alice", 25},
        {"Bob", 20},
        {"Charlie", 30},
    }

    sort.Sort(ByAge(people))

    fmt.Println(people)
}

この例では、Person型のスライスをByAge型にキャストしています。ByAge型には、Len()Swap()Less()という3つのメソッドが定義されています。これらのメソッドは、カスタム型に合わせて定義する必要があります。

Less()メソッドでは、a[i].Age < a[j].Ageという比較式が使用されています。この式により、Person型のスライスが年齢順にソートされます。

スライスの部分的なソート

Golangの「sort」パッケージは、スライスの一部分だけをソートするための機能も提供しています。sort.Slice()メソッドには、startendという2つの引数があります。これらの引数を使用すると、スライスの一部分だけをソートできます。

以下は、スライスの一部分だけをソートする例です。

package main

import (
    "fmt"
    "sort"
)

func main() {
    slice := []int{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}

    sort.Slice(slice[3:8], func(i, j int) bool {
        return slice[3:8][i] < slice[3:8][j]
    })

    fmt.Println(slice)
}

この例では、スライスの3番目から8番目までの要素をソートしています。sort.Slice()メソッドの第1引数には、スライスの一部分を指定しています。start引数は、ソートする部分スライスの開始インデックスを指定します。end引数は、ソートする部分スライスの終了インデックスの次のインデックスを指定します。

sort.Slice()メソッドの第2引数には、ソートする方法を指定する関数を定義しています。この例では、slice[3:8]の要素を昇順にソートするために、無名関数が使用されています。この無名関数のijの要素を比較して、slice[3:8][i]slice[3:8][j]より小さい場合にはtrueを返し、そうでない場合にはfalseを返します。

反転した順序でのソート

Golangの「sort」パッケージは、スライスを反転した順序でソートする機能も提供しています。sort.Reverse()メソッドを使用すると、スライスを反転した順序でソートすることができます。

以下は、スライスを反転した順序でソートする例です。

package main

import (
    "fmt"
    "sort"
)

func main() {
    slice := []int{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}

    sort.Sort(sort.Reverse(sort.IntSlice(slice)))

    fmt.Println(slice)
}

この例では、sort.Reverse()メソッドにsort.IntSlice(slice)を渡して、スライスを反転した順序でソートしています。

まとめ

Golangの「sort」パッケージを使用することで、スライスをソートすることができます。このパッケージには、スライスのソート、カスタム型のスライスのソート、スライスの部分的なソート、スライスの反転した順序でのソートなど、さまざまな機能があります。ソートの方法を指定するためには、比較関数を定義する必要があります。比較関数は、lessメソッドとして定義することができます。スライスの一部分だけをソートする場合は、sort.Slice()メソッドを使用し、スライスを反転した順序でソートする場合は、sort.Reverse()メソッドを使用します。これらのメソッドを使用することで、効率的かつ簡単にスライスをソートすることができます。