Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
sort パッケージ
Goの『sort』パッケージを使うとスライスや任意のコレクションを並べ替えできます。整数・文字列・浮動小数点数はそれぞれ専用の関数があり、任意の型には『sort.Slice()』を使います。
構文
import "sort"
// 整数・文字列・float64スライスを昇順にソートします。
sort.Ints([]int{3, 1, 2})
sort.Strings([]string{"banana", "apple", "cherry"})
sort.Float64s([]float64{3.14, 1.41, 2.71})
// 任意のスライスをカスタムルールでソートします。
sort.Slice(s, func(i, j int) bool {
return s[i] < s[j] // trueを返す条件で並べ替えます。
})
// ソート済みスライスの二分探索を行います。
idx := sort.SearchInts(nums, 5)
// ソート済みかどうかを確認します。
ok := sort.IntsAreSorted(nums)
関数一覧
| 関数 | 概要 |
|---|---|
| sort.Ints(a) | int スライスを昇順にソートします(インプレース)。 |
| sort.Strings(a) | string スライスを昇順にソートします(インプレース)。 |
| sort.Float64s(a) | float64 スライスを昇順にソートします(インプレース)。 |
| sort.Slice(s, less) | 任意スライスをless関数の結果に基づいてソートします。 |
| sort.SliceStable(s, less) | sort.Sliceと同様ですが等しい要素の順序を保持します。 |
| sort.Search(n, f) | 二分探索で条件fを満たす最小インデックスを返します。 |
| sort.SearchInts(a, x) | ソート済みint スライスでxの挿入位置を返します。 |
| sort.SearchStrings(a, x) | ソート済みstring スライスでxの挿入位置を返します。 |
| sort.IntsAreSorted(a) | int スライスが昇順かどうかを返します。 |
| sort.StringsAreSorted(a) | string スライスが昇順かどうかを返します。 |
| sort.Reverse(data) | Interfaceをラップして降順にします。 |
サンプルコード
package main
import (
"fmt"
"sort"
)
// Person:構造体のソート例で使います。
type Person struct {
Name string
Age int
}
func main() {
// 整数スライスのソートです。
nums := []int{5, 2, 8, 1, 9, 3}
fmt.Println("ソート前:", nums)
sort.Ints(nums)
fmt.Println("ソート後(昇順):", nums)
// 逆順(降順)にソートします。
sort.Sort(sort.Reverse(sort.IntSlice(nums)))
fmt.Println("ソート後(降順):", nums)
fmt.Println()
// 文字列スライスのソートです。
words := []string{"banana", "apple", "cherry", "date"}
fmt.Println("文字列ソート前:", words)
sort.Strings(words)
fmt.Println("文字列ソート後:", words)
fmt.Println()
// 構造体スライスをカスタムルールでソートします。
people := []Person{
{"Alice", 30},
{"Bob", 25},
{"Carol", 35},
{"Dave", 25},
}
fmt.Println("--- 構造体を年齢で昇順ソート ---")
sort.Slice(people, func(i, j int) bool {
return people[i].Age < people[j].Age // 年齢が小さい順にします。
})
for _, p := range people {
fmt.Printf(" %s: %d歳\n", p.Name, p.Age)
}
// 年齢が同じとき名前順を維持(安定ソート)します。
fmt.Println("--- 安定ソート(年齢昇順、同年齢は元の順序を保持)---")
people2 := []Person{
{"Alice", 30}, {"Bob", 25}, {"Carol", 35}, {"Dave", 25},
}
sort.SliceStable(people2, func(i, j int) bool {
return people2[i].Age < people2[j].Age
})
for _, p := range people2 {
fmt.Printf(" %s: %d歳\n", p.Name, p.Age)
}
fmt.Println()
// ソート済みスライスの二分探索です。
sorted := []int{1, 3, 5, 7, 9, 11}
idx := sort.SearchInts(sorted, 7)
fmt.Printf("7のインデックス: %d(値: %d)\n", idx, sorted[idx])
fmt.Println("IntsAreSorted:", sort.IntsAreSorted(sorted))
}
概要
『sort.Slice()』は最も汎用的なソート関数で、任意の型に対してカスタムの比較ロジックを使えます。比較関数は「i番目の要素がj番目の要素より前に来るべきならtrue」を返します。
Go 1.21以降では『slices.Sort()』(slicesパッケージ)が導入され、ジェネリクスを使ったより簡潔な書き方ができます。新しいコードでは slices パッケージの使用も検討してください。
sort.Slice()は不安定ソートです。等しい要素の相対順序を保持したい場合はsort.SliceStable()を使ってください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。