この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
go-linq という LINQ 風に検索できるライブラリを試してみました。使い方自体は go-linq のREADMEを見れば分かったのですが、自分なりにも試してみたいと思い、以前 紹介した gofakeit と組み合わせサンプルプログラムを書いてみました。
以下、そのサンプルプログラムについてとなります。
プログラムと実行について
Golangを実行できる環境にて、「go get」で予め使用するライブラリをインストールしておきます。
$ go get github.com/brianvoe/gofakeit/v6
$ go get github.com/ahmetb/go-linq/v3
今回書いたプログラムは以下となります。以前と同様「gofakeit」でビールに関するダミーデータを作り、そのデータから「go-linq」を使ってビールのモルト(Malt)数での逆ソート、モルト毎のカウントをやってみました。
package main
import (
"fmt"
"strings"
. "github.com/ahmetb/go-linq/v3"
"github.com/brianvoe/gofakeit"
)
type Beer struct {
ID int `csv:"id"`
Malt string `csv:"malt"`
Name string `csv:"name"`
Style string `csv:"style"`
}
func main() {
gofakeit.Seed(0)
var beers []Beer
for i := 0; i < 10; i++ {
b := &Beer{
gofakeit.Number(1, 100),
gofakeit.BeerMalt(),
gofakeit.BeerName(),
gofakeit.BeerStyle(),
}
beers = append(beers, *b)
}
for _, b := range beers {
fmt.Printf("id : %v, malt : %s, name : %s\n", b.ID, b.Malt, b.Name)
}
var malts []string
From(beers).
Select(func(b interface{}) interface{} {
return b.(Beer).Malt
}).
GroupBy(
func(malt interface{}) interface{} {
return malt
}, func(malt interface{}) interface{} {
return malt
}).
OrderByDescending(
func(g interface{}) interface{} {
return len(g.(Group).Group)
}).
Select(
func(g interface{}) interface{} {
return g.(Group).Key
}).
ToSlice(&malts)
for _, m := range malts {
c := From(beers).Where(func(b interface{}) bool {
return strings.Contains(b.(Beer).Malt, m)
}).Select(func(b interface{}) interface{} {
return b.(Beer).Name
}).Count()
fmt.Printf("malt = %s, count = %v\n", m, c)
}
}
19〜30行目で「gofakeit」を使ってダミーデータを生成しています。この辺りは以前とかわっておりません。「go-linq」を使った検索は36行目以降となります。36〜55行目で、ビール毎のモルト(Malt)の数で逆順でソートしています。構文的にはループを使わず「GroupBy()」や「OrderByDescending()」を使って検索していることが分かるかと思います。次に58〜62行目で、モルト(Malt)毎のカウントを行なっております。こちらもモルト毎のカウント自体にはループを使わず「Count()」を使っております。
実行してみると、以下のように生成したダミーデータ、モルト(Malt)数の逆順でカウントした結果が出力されます。(※ダミーデータはランダムで生成となるので毎回実行結果は異なります)
id : 5, malt : Victory, name : Péché Mortel
id : 36, malt : Roasted barley, name : Yeti Imperial Stout
id : 89, malt : Rye malt, name : Maudite
id : 83, malt : Vienna, name : La Fin Du Monde
id : 48, malt : Caramel, name : Sublimely Self-Righteous Ale
id : 57, malt : Rye malt, name : Founders Kentucky Breakfast
id : 64, malt : Special roast, name : Sierra Nevada Celebration Ale
id : 19, malt : Special roast, name : Samuel Smith’s Imperial IPA
id : 33, malt : Rye malt, name : Maharaj
id : 31, malt : Chocolate malt, name : Storm King Stout
malt = Rye malt, count = 3
malt = Special roast, count = 2
malt = Caramel, count = 1
malt = Chocolate malt, count = 1
malt = Victory, count = 1
malt = Roasted barley, count = 1
malt = Vienna, count = 1
sliceに複数件持たせたデータからの検索やカウントという良くある処理について、「Select()」「Groupby()」などで絞り込んでいけることが新鮮でした。何かの役に立てば幸いです。