💬

Goにおける配列(スライス)操作でFilterとかMapとか使いたい

2021/01/14に公開1

Goにおける配列(スライス)の操作って皆どうやってるんですかね?
筋力(for文)で書きなぐるんですかね?
なんかカッチョいいライブラリ使うんですかね?(邪道と言われるかも)

自分が実務でGoを3年書いた上での意見は下記です。
基本は筋力(for文)で書くけど、可読性が損なわれそうな箇所はライブラリを使ってでも処理を追いやすく見やすい形で書きたい

例えば、簡単な集計処理を書いたり、ネストが多い操作や入れ替えが発生したりした時は筋力(for文)で書いていると疲れるし、見づらいし、一時変数は無駄に多くなるし、バグが有っても探すの大変そうだし良い事ないなと思いました。

そこで、配列操作に便利なライブラリを探しました。

候補1: go-funk

https://github.com/thoas/go-funk

良い感じですが、メソッドチェーンしたい事が多かったので別のを探す

候補2: koazee

https://github.com/wesovilabs/koazee

めっちゃやれること多い!メソッドチェーンもできる!

Operation Description Since
Add It adds a new element in the last position v0.0.1
At It returns the element in the given position v0.0.1
Contains It checks if the given element is found in the stream. v0.0.1
Count It returns the number of elements in a stream v0.0.1
DeleteAt It remove the elements in the given position v0.0.3
Drop It removes an element from the stream v0.0.1
DropWhile It removes the elements in the stream that match with the given input function v0.0.4
Filter It discards those elements that doesn't match with the provided filter v0.0.1
First It returns the element in the first position v0.0.1
ForEach It does something over all the elements in the stream. v0.0.1
GroupBy It creates groups depending on the returned function value v0.0.4
IndexOf It returns the first index of the element in the stream. v0.0.3
IndexesOf It returns the index for all the occurrences of the element in the stream. v0.0.4
Last It returns the element in the last position v0.0.1
LastIndexOf It returns the last occurrence for the element in the stream. v0.0.3
Map It converts the element in the stream v0.0.1
Pop It extracts the first element in the stream and return this and the new stream v0.0.3
Reduce It reduceshe stream to a single value by executing a provided function for each value of the stream v0.0.1
RemoveDuplicates It removes duplicated elements. v0.0.1
Reverse It reverses the sequence of elements in the stream. v0.0.3
Set It replaces the element in the given index by the provided value v0.0.3
Sort It sorts the elements in the stream v0.0.1
Take It returns a stream with the elements between the given indexes v0.0.3

でも更新がだいぶ前で止まっているし、Filterして配列が空になった時にMapするとクラッシュするし、キャッシュ使ってる影響で同じ条件で別の配列を使うと前の配列のデータが混じる等バグが多い

候補3: gen

https://github.com/clipperhouse/gen

流行りのコード生成系のライブラリ
一番早くて汎用性ありそうだけど、DBスキーマと違って気軽に様々な形を使う配列で自動生成は向いてないのではと思っています。

候補4: 自作

https://github.com/rabee-inc/go-pkg/blob/master/sliceutil/stream.go

出たオレオレライブラリ(^q^)
koazeeのI/Fを参考に書いてみました。
メリットはバグがあった時にサクッと直せたり、欲しい機能あったらサクッと拡張できる所ですかね。できる(自作なのであたりまえ)

結論

結局、2年くらい自作ライブラリでやっています。
やっぱ自社の都合に合わせて自由に修正&追加できるのは便利だし、仕事すればするほど最適化されていくのは便利ですよね。

感想

Goの実装はシンプルなので、変にブラックボックス化する事はないとおもうので、このくらいの簡単なユーティリティなら他のイケてるOSSのI/Fを参考にして自作してっちゃうのが良い気がしています。

Discussion

元ピペド元ピペド

はじめまして。
素晴らしい記事ですね。自作できるのすごいです。

C#のLINQを普段使ってる人をターゲットに(?)、go-linqというライブラリもあります。
https://github.com/ahmetb/go-linq

メソッドチェーンもできますが、interface{}の嵐になるので、実行時キャストエラーには注意する必要があります。jsに慣れている人にとっては逆に楽しめるかもしれません。

Generics機能が将来Goにリリースされたら、この分野のライブラリ全般が型安全に書けて盛り上がりそうですよね。