Golang にてスライス(配列)のソート

Golang のソートは最初使い方がいまいち分かりにくかった。
パッケージを探すと sort というのが出てくるけど、
何も読まずに普通に使ってみるとエラーが出る。

// lists: 何か配列
sort.Sort(lists)
fmt.Print(lists)

エラーが出る

cannot use lists (type Lists) as type sort.Interface in argument to sort.Sort:
Lists does not implement sort.Interface (missing Len method)
Lists does not implement sort.Interface (missing Less method)
Lists does not implement sort.Interface (missing Swap method)

sort の Example と各メソッドを見ないと分からないと思う。

ソートをするには

スライス(配列)をソートするには、
スライス(配列)を Interface インターフェースの条件を満たした状態にしないといけない。
Interface インターフェースは、Len()、Less()、Swap() のメソッドが必要。らしい。

以下 Example 抜粋。

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 }

sort

sort.Interface

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)
}

サンプルコード

  • Less(i, j int) bool はソートの基準となるプロパティを指定する。
  • map[int] とかでも試してみたけどマップはうまく動かなかった。

sort.go

package main

import (
	"fmt"
	"sort"
)

type Users struct {
	ID int
	Name string
}

type Lists []Users

func (l Lists) Len() int {
	// Len is the number of elements in the collection.
	return len(l)
}

func (l Lists) Less(i, j int) bool {
	// Less reports whether the element with
	// index i should sort before the element with index j.
	return l[i].ID < l[j].ID
	// return i < j ← これだとうまく動かない
}

func (l Lists) Swap(i, j int) {
	// Swap swaps the elements with indexes i and j.
	l[i], l[j] = l[j], l[i]
}

func main() {

	lists := Lists{}
	lists = append(lists, Users{ ID: 1, Name: "test1" })
	lists = append(lists, Users{ ID: 7, Name: "test7" })
	lists = append(lists, Users{ ID: 2, Name: "test2" })
	lists = append(lists, Users{ ID: 6, Name: "test6" })
	lists = append(lists, Users{ ID: 3, Name: "test3" })
	lists = append(lists, Users{ ID: 5, Name: "test5" })
	lists = append(lists, Users{ ID: 4, Name: "test4" })

	fmt.Println(lists)

	sort.Sort(lists)
	fmt.Println(lists)

	sort.Sort(sort.Reverse(lists))
	fmt.Println(lists)
}
$ go run sort.go
[{1 test1} {7 test7} {2 test2} {6 test6} {3 test3} {5 test5} {4 test4}]
[{1 test1} {2 test2} {3 test3} {4 test4} {5 test5} {6 test6} {7 test7}]
[{7 test7} {6 test6} {5 test5} {4 test4} {3 test3} {2 test2} {1 test1}]
カテゴリー:Go