はじめに
Qiita初投稿です。
自分がGo言語で配列操作をするとき、rangeを使ってぐるぐるループを回して処理することが多いのですが、
ふと、rubyで言う map
, filter
, each
などを作って使いたくなっては、
「わざわざ作るのもめんどうだしなぁ」と、すぐ諦めてしまいます。
そこで今回は、Advent Calendarの季節でもあり、よい機会なので、
試しにPlaygroundで作ってみることにしました。
作ったメソッドたち
1. filter
package main
import (
"fmt"
)
func filter(nums []int, funcs ...func(n int) bool) []int {
if len(funcs) == 0 {
return nums
}
ret := make([]int, 0, len(nums))
f := funcs[0]
for i, n := range nums {
if f(n) {
ret = append(ret, nums[i])
}
}
return filter(ret, funcs[1:]...)
}
func main() {
nums := []int{1, 2, 3}
nums = filter(
nums,
func(n int) bool {
if n > 1 {
return true
}
return false
},
func(n int) bool {
if n > 2 {
return true
}
return false
},
)
fmt.Println(nums)
}
- 可変長引数にして、フィルタ条件を複数受け付けられるようにした
- 久々に再帰をみた
2. map
package main
import (
"fmt"
)
func mapToI(nums []int, f func(n int) int) []int {
ret := make([]int, len(nums))
for i, n:= range nums {
ret[i] = f(n)
}
return ret
}
func main() {
nums := []int{1, 2, 3}
nums = mapToI(nums, func(n int) int {
return n*n
})
fmt.Println(nums)
}
- よく使うint, stringあたりだけ作ると便利なこともあるかも
3. each
package main
import (
"fmt"
)
func each(nums []int, f func(n int)) {
for _, n:= range nums {
f(n)
}
}
func main() {
nums := []int{1, 2, 3}
each(nums, func(n int) {
fmt.Println(n)
})
fmt.Println(nums)
}
- うーん、これくらいだと作ってあってもなくても変わらない感
4. uniq
package main
import (
"fmt"
)
func uniq(nums []int) []int {
ret := make([]int, 0, len(nums))
numsMap := make(map[int]struct{}, len(nums))
for _, n := range nums {
if _, ok := numsMap[n]; !ok {
numsMap[n] = struct{}{}
ret = append(ret, n)
}
}
return ret
}
func main() {
nums := []int{1, 1, 3}
nums = uniq(nums)
fmt.Println(nums)
}
https://play.golang.org/p/HB0gk4zVF_
- これは作っておくと地味に便利かも
- uniqueとったIDの配列でデータベースにアクセスするのとか簡単になりそ
おわりに
ほかにも、「こういうメソッド生やしておくと便利だよ」というものがあれば教えてください。