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のほうがその場で動かせるし、自由にコードいじって「ここをこうするとどうなるんだ?」みたいなのができて大変良いです。

参考リンク