#Golang】標準パッケージ sort
Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。
package main
//https://golang.org/pkg/sort/
import (
"fmt"
"sort"
)
//sortを自分で実装する場合
/*func sort(list []int) {
eNum := len(list)
for i := eNum; i > 0; i-- {
for j := 0; j < i-1; j++ {
if list[j] > list[j+1] {
list[j], list[j+1] = list[j+1], list[j]
}
}
}
}
list := []int{3, 4, 1, 2, 8, 5}
sort(list)
fmt.Println(list)
*/
type Entry struct {
name string
value int
}
type List []Entry
//カスタム
//長さ(キーと値)
func (l List) Len() int {
return len(l)
}
//交換
func (l List) Swap(i, j int) {
l[i], l[j] = l[j], l[i]
}
//値
func (l List) Less(i, j int) bool {
if l[i].value == l[j].value {
return (l[i].name < l[j].name)
} else {
return (l[i].value < l[j].value)
}
}
func main() {
//宣言
i := []int{5, 3, 2, 4, 5, 6, 4, 8, 9, 8, 7, 10}
s := []string{"a", "z", "j"}
//struct 関数内でしか使わない婆はこのように書ける
p := []struct {
Name string
Age int
}{
{"A", 20},
{"F", 40},
{"i", 30},
{"b", 10},
{"t", 15},
{"y", 30},
{"c", 30},
{"w", 30},
}
fmt.Println(i, s, p)
//ソート
//スライス、配列
//integerをソート
sort.Ints(i)
//stringをソート
sort.Strings(s)
//struct (mapではないが) ver1 structソート(mapではなくstructにしてからソートすれば、同じように使える)
sort.Slice(p, func(i, j int) bool { return p[i].Name < p[j].Name })
fmt.Println(i, s, p)
sort.Slice(p, func(i, j int) bool { return p[i].Age < p[j].Age })
fmt.Println(p)
//sort.Sliceとsort.SliceStable
//Goのsort packageには、安定ソートを保証しないSlice関数と安定ソートを保証するSliceStableが存在する。
//破壊的(SliceStable)かそうじゃないか(Slice)
//SliceStableは、ソート前の順序が、ソート後も保存されている。
//SliceStableは、ソート後のデータは、同じAgeのPはName順で並んでいる。
sort.Slice(p, func(i, j int) bool { return p[i].Name < p[j].Name })
sort.Slice(p, func(i, j int) bool { return p[i].Age < p[j].Age })
fmt.Println(p)
//>>[{b 10} {t 15} {A 20} {y 30} {c 30} {i 30} {w 30} {F 40}]
sort.SliceStable(p, func(i, j int) bool { return p[i].Name < p[j].Name })
sort.SliceStable(p, func(i, j int) bool { return p[i].Age < p[j].Age })
fmt.Println(p)
//>>[{b 10} {t 15} {A 20} {c 30} {i 30} {w 30} {y 30} {F 40}]
//map ver2 基本はstructにしてやるver1でOKだが一応
//ソートして順番通りに列挙する
//キーをスライス(配列)にして、それをソートする。
//そのソートしたキーのスライスを使って何らかの順序でマップの値を取り出す。
m := map[string]int{"B": 100, "C": 200, "A": 300}
a := make([]string, len(m), len(m))
//キーをaに入れる
ii := 0
for key := range m {
a[ii] = key
ii++
}
// キーを入れたスライスをソートする
sort.Strings(a)
for iii := 0; iii < len(a); iii++ {
fmt.Println(a[iii], m[a[iii]])
}
//map ver3 基本はstructにしてやるver1でOKだが一応
/*
マップを値で降順、値が等しい場合キーで昇順にソートする
条件式を指定したソート と同様のことを行います。
条件式を指定したソート...
Len(),Less(),Swap()という3つのメソッドを 実装したクラスを作れば、独自条件のソートが可能です。
*/
m2 := map[string]int{"ada": 1, "hoge": 4, "basha": 3, "poeni": 3}
a2 := List{}
for k, v := range m2 {
e := Entry{k, v}
a2 = append(a2, e)
}
sort.Sort(a2)
fmt.Println(a2)
}