最終更新:2020/05/25
Go言語はsortパッケージを使ってデータを並び替えることができます。 IntやFloatなどの数値だけでなく、struct構造体に宣言されているフィールドの値で並び替えることもできます。
目次
1. sortインターフェース
Go言語のsortパッケージにインターフェースが宣言されています。
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with
// index i should sort before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
上記のインターフェースで宣言されているメソッドを、ソートしたい対象のstructで追加実装します。
(Go言語は、インタフェースのメソッドをstructに追加すると、インターフェースを実装したことになります。)
2. structでsortインターフェースを実装する
structにInterfaceの関数を実装します。
サンプルコードとして、ユーザー情報を管理するUser structを使います。
package model
import (
"github.com/jinzhu/gorm"
)
// User is struct.
type User struct {
ID int
FirstName string
LastName string
Email string
Gender int
}
上記はuser情報を管理するだけのstructです。
このuser structにコードを追加します。
// ByID is Users Slice for Sort.
type ByID []User
func (id ByID) Len() int { return len(id) }
func (id ByID) Swap(i, j int) { id[i], id[j] = id[j], id[i] }
func (id ByID) Less(i, j int) bool { return id[i].ID < id[j].ID }
必要なのはこれだけです。
ソート対象はIDです。
func (id ByID) Less(i, j int) bool { return id[i].ID < id[j].ID }
typeで宣言しているのは、ユーザー構造体スライスの別名宣言です。
type ByID []User
GO言語では、typeを使うと、既存の型や型リテラルに別名をつけることができます。
以上の宣言だけで、sortパッケージに用意されている関数でソート処理ができます。
3. ソートを実行する
上記のコードを使ってソートを実装します。
以下のコードを追加します。
// SortByUserID sorts User objects by ID.
func SortByUserID(users []User) []User {
sort.Sort(ByID(users))
return users
}
typeで宣言したスライスに構造体の配列を設定してSortメソッドを呼び出します。
sort.Sort(ByID(users))
sortパッケージのSortメソッドが呼び出されます。
引数に渡した構造体配列がID順に並び替えられます。
Sortメソッドのコードも読んでおきましょう。
// Sort sorts data.
// It makes one call to data.Len to determine n, and O(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
n := data.Len()
quickSort(data, 0, n, maxDepth(n))
}
Len関数とquickSort関数が呼び出されています。
つまり、structで宣言したLen、Swap,Less関数をインテーフェースを介して呼び出すことでSortを実行しています。
うまくできていますね。
今回のように、ライブラリなどのソースコードはブラックボックスのままにしないで常にコードを確認する癖をつけておきましょう。
勉強にもなるし、Go言語のSort処理はクイックソートで実装されていることもわかります。