2016/10/04

Recent entries from same category

  1. バイナリ一つで zip, tar.gz, tar.bz2, tar.xz が開けるコマンド「archiver」(と go1.8 への対応方法)
  2. Golang 1.8 でやってくる database/sql の変更点
  3. GolangでAPI Clientを実装する、の続き
  4. golang で終了を確認するテストの書き方
  5. golang でパフォーマンスチューニングする際に気を付けるべきこと

golang では配列をソートしたい場合に癖があり、Int や Float64、String といった固定の型であれば sort パッケージが提供する関数でソートが可能でしたが、独自の型や Int64 等といった sort パッケージが用意していない型の配列をソートするには Sorter というインタフェースを備えた型で扱うしかありませんでした。

package main

import (
    "fmt"
    "sort"
)

type Food struct {
    Name  string
    Price int
}

type Foods []Food

func (f Foods) Len() int {
    return len(f)
}

func (f Foods) Less(i, j intbool {
    return f[i].Price < f[j].Price
}

func (f Foods) Swap(i, j int) {
    f[i], f[j] = f[j], f[i]
}

func main() {
    foods := make([]Food, 3)
    foods[0= Food{Name: "みかん", Price: 150}
    foods[1= Food{Name: "バナナ", Price: 100}
    foods[2= Food{Name: "りんご", Price: 120}


    sort.Sort(Foods(foods))

    for _, food := range foods {
        fmt.Printf("%+v\n", food)
    }
}

この件に関して、GitHub の issues で多くの議論が行われました。

sort: make sorting easier, add Slice, SliceStable, SliceIsSorted, reflect.Swapper - Issue #16721 - golang/go - GitHub

Summary of problem 1. Vast majority of sort.Interface uses a slice 2. Have to define a new top level...

https://github.com/golang/go/issues/16721

僕も sort を簡単にする sorter というパッケージを公開したりもしていましたが、昨晩 sort.Slice, sort.SliceStable, sort.SliceIsSorted という3つの関数が master ブランチに入りました。

sort: add Slice, SliceStable, and SliceIsSorted - golang/go@22a2bdf - GitHub

Add helpers for sorting slices. Slice sorts slices: sort.Slice(s, func(i, j int) bool { if s[i].Foo ...

https://github.com/golang/go/commit/22a2bdfedb95612984cec3141924953b88a607b7

これにより上記のコードが以下の様にスッキリと書ける様になりました。

package main

import (
    "fmt"
    "sort"
)

type Food struct {
    Name  string
    Price int
}

func main() {
    foods := make([]Food, 3)
    foods[0= Food{Name: "みかん", Price: 150}
    foods[1= Food{Name: "バナナ", Price: 100}
    foods[2= Food{Name: "りんご", Price: 120}

    sort.Slice(foods, func(i, j intbool {
        return foods[i].Price < foods[j].Price
    })

    for _, food := range foods {
        fmt.Printf("%+v\n", food)
    }
}

とても良いですね。SliceStable は安定ソート、SliceIsSorted はそのスライスがソート済みかどうかを返します。

まぁあるべき姿になったという感じ。

みんなのGo言語【現場で使える実践テクニック】 みんなのGo言語【現場で使える実践テクニック】
松木雅幸, mattn, 藤原俊一郎, 中島大一, 牧 大輔, 鈴木健太
技術評論社 / ¥ 2,138 (2016-09-09)
 
発送可能時間:在庫あり。


blog comments powered by Disqus