sort パッケージ
| 対応: | Go 1.0(2012) |
|---|
Goの『sort』パッケージを使うとスライスや任意のコレクションを並べ替えできます。整数・文字列・浮動小数点数はそれぞれ専用の関数があり、任意の型には『sort.Slice()』を使います。
構文
import "sort"
// 整数・文字列・float64スライスを昇順にソートします。
sort.Ints([]int{3, 1, 2})
sort.Strings([]string{"常守朱", "狡噛慎也", "宜野座伸元"})
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をラップして降順にします。 |
サンプルコード
sample_sort_package.go
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{"狡噛慎也", "常守朱", "宜野座伸元", "征陸智己"}
fmt.Println("文字列ソート前:", words)
sort.Strings(words)
fmt.Println("文字列ソート後:", words)
fmt.Println()
// 構造体スライスをカスタムルールでソートします。
people := []Person{
{"狡噛慎也", 28},
{"常守朱", 20},
{"宜野座伸元", 28},
{"征陸智己", 59},
}
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{
{"狡噛慎也", 28}, {"常守朱", 20}, {"宜野座伸元", 28}, {"征陸智己", 59},
}
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))
}
go run sort_package.go ソート前: [5 2 8 1 9 3] ソート後(昇順): [1 2 3 5 8 9] ソート後(降順): [9 8 5 3 2 1] 文字列ソート前: [狡噛慎也 常守朱 宜野座伸元 征陸智己] 文字列ソート後: [宜野座伸元 常守朱 征陸智己 狡噛慎也] --- 構造体を年齢で昇順ソート --- 常守朱: 20歳 狡噛慎也: 28歳 宜野座伸元: 28歳 征陸智己: 59歳 --- 安定ソート(年齢昇順、同年齢は元の順序を保持)--- 常守朱: 20歳 狡噛慎也: 28歳 宜野座伸元: 28歳 征陸智己: 59歳 7のインデックス: 3(値: 7) IntsAreSorted: true
概要
『sort.Slice()』は最も汎用的なソート関数で、任意の型に対してカスタムの比較ロジックを使えます。比較関数は「i番目の要素がj番目の要素より前に来るべきならtrue」を返します。
Go 1.21以降では『slices.Sort()』(slicesパッケージ)が導入され、ジェネリクスを使ったより簡潔な書き方ができます。新しいコードでは slices パッケージの使用も検討してください。
『sort.Slice()』は不安定ソートです。等しい要素の相対順序を保持したい場合は『sort.SliceStable()』を使ってください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。