はじめに
jsでよくやっているこんな感じのコードをGoでも書きたい。けど外部のパッケージは入れたくない場合の対処法を紹介します。
type Skill = {
name: string
}
const skills: Skill[] = [
{ name: 'Ruby' },
{ name: 'Javascript' },
{ name: 'Python' },
]
const py = skills.find(s => s.name === 'Python')
// => {name: "Python"}
console.log(py)
const names = skills.map(s => s.name)
// => (3) ["Ruby", "Javascript", "Python"]
console.log(names)
find
まず適当にsliceを用意。
package main
type skill struct {
name string
}
func main() {
skills := []skill{
{name: "Ruby"},
{name: "Javascript"},
{name: "Python"},
}
}
sliceに型をつける。
package main
type skill struct {
name string
}
type skills []skill
func main() {
skills := []skill{
{name: "Ruby"},
{name: "Javascript"},
{name: "Python"},
}
}
sliceにメソッド定義をして、mainの中で呼び出します。
package main
import "fmt"
type skill struct {
name string
}
type skills []skill
func (s skills) find(findFunc func(s skill) bool) skill {
for _, sk := range s {
if findFunc(sk) {
return sk
}
}
return skill{}
}
func main() {
skills := skills{
{name: "Ruby"},
{name: "Javascript"},
{name: "Python"},
}
s1 := skills.find(func(s skill) bool { return s.name == "Python" })
fmt.Printf("found skill: %+v\n", s1) // found skill: {name:Python}
s2 := skills.find(func(s skill) bool { return s.name == "Go" })
fmt.Printf("found skill: %+v\n", s2) // found skill: {name:}
}
map
mapも同じ要領で実装してみます。関数名がmapだとgoの予約語と被ってエラーが出るので、publicのMapにしています。あまりいけてないので良い名前があればお教えいただけますと幸いです🙇♂️
package main
import "fmt"
type skill struct {
name string
}
type skills []skill
func (s skills) Map(mapFunc func(s skill) interface{}) []interface{} {
var ret []interface{}
for _, sk := range s {
ret = append(ret, mapFunc(sk))
}
return ret
}
func main() {
skills := skills{
{name: "Ruby"},
{name: "Javascript"},
{name: "Python"},
}
n1 := skills.Map(func(s skill) interface{} { return s.name })
fmt.Printf("mapped skill: %+v\n", n1) // mapped skill: [Ruby Javascript Python]
}
おわりに
意外に簡単にできました。
slicesごとに定義するのは面倒なので、使いまわせるようにしたいですが、あまり良い方法が浮かびませんでした。
やはりパッケージを使うしか無いのか🤔