Help us understand the problem. What is going on with this article?

Go言語でコレクション処理のメソッドを作ってみた #golang

More than 3 years have passed since last update.

はじめに

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)
}

https://play.golang.org/p/8bqykZCbSU

  • 可変長引数にして、フィルタ条件を複数受け付けられるようにした
  • 久々に再帰をみた

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)
}

https://play.golang.org/p/R5CQCRWh7L

  • よく使う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)
}

https://play.golang.org/p/d2lgAgPQuG

  • うーん、これくらいだと作ってあってもなくても変わらない感

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の配列でデータベースにアクセスするのとか簡単になりそ

おわりに

ほかにも、「こういうメソッド生やしておくと便利だよ」というものがあれば教えてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away