Delete Go Map entry and rename Go Map key
Mapの操作を色々する機会があったのでまとめてみます。
それぞれのセクションごとに動作するコードのリンクがあります。play.golang.org上にあるので、その場で実行することができます。
ゴール
pathみたいに/
区切りの文字列をキーとして持っているMapに対し、特定の条件を持つキーを削除したり、キー名を変更する。
普通はそんなこと意識しないようにMap作っていくと思うんだけど人生は長い。Mapのキーをごにょごにょしたいときもある。
Mapの作成
いくつか作成方法はありますが今回は以下のように作成。このMapをごにょごにょしていきます。
func defineMap() map[string]int {
m := map[string]int{
"/tabemono/fruit/apple/hoge": 1,
"/tabemono/fish/carp/fuga": 4,
"/tabemono/fruit/pear/piyo": 100,
"/tabemono/fish/mackerel/hage": 45,
}
return m
}
Mapのキーに特定のキーワードが入っていた場合そのエントリを削除する
キーに特定のキーワードが入っていた場合、そのエントリを削除します。
regexp.MustCompile()
で正規表現を解析し、テキストと比較できるオブジェクトを返します。for
でMapのキーを1つずつ取り出し、MatchString()
でキーの文字列と正規表現を比較します。一致した場合はtrue、不一致の場合はfalseを返します。
true場合はdelete()
でそのキーを削除しています。今回動作させたコードでは、fish
を含むキーのエントリを削除しています。
func removeKeyword(m map[string]int, kw string) map[string]int {
r := regexp.MustCompile(kw)
for i := range m {
if r.MatchString(i) {
delete(m, i)
}
}
return m
}
Mapのキーをリネームする
キーをリネームします。リネームする関数は無い(と思う…)ので、キーをリネームするためにMapを作り直しています。
まず新しくtm
というMapを定義しています。このMapを元のMapのキーをリネームした新Mapとして使います。
for
でMapのキーを1つずつ取り出し、strings.Split()
で指定してデリミタ(今回は/
)で文字列をスライスにします。そして新たにt
という変数を定義し、スライスの後ろから2番目(今回全てのキーの後ろから2番目の文字が食べ物の名前となっているので)の文字列を格納します。
スライスの後ろから2番目を格納したt
と元のMapからfor
で取得したバリューを使って、新たに作成したMapであるtm
に追加していきます。
これで元のMapm
のキーをリネームしたMapであるtm
が完成 = Mapのキーのリネームができました。
func tabemonoName(m map[string]int) map[string]int {
tm := map[string]int{}
for i, v := range m {
s := strings.Split(i, "/")
t := s[len(s)-2]
tm[t] = v
}
return tm
}
Mapを整形して出力
map[pear:100 apple:1]
のような出力では見づらいので、人に優しい出力に整形します。
for
でMapからキーとバリューを取り出し、都度出力していきます。
func printMap(m map[string]int) {
for i, v := range m {
fmt.Printf("%s%d\n", i+": ", v)
}
}
感想
for
便利。「Mapのキーをリネームする」という操作が調べても見つからず苦労しました。多分普通そんなことする必要がないからだと思いますが…。
あと今回動くコード置き場としてhttps://play.golang.org/を使ったんですがこれ便利ですね…。最初Gistを使おうと思ったんですがplay.golang.orgのほうがその場で動かせるし、自由にコードいじって「ここをこうするとどうなるんだ?」みたいなのができて大変良いです。