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)

}

bannerAds