読者です 読者をやめる 読者になる 読者になる

覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。 twitter: @yyoshikaw

Go言語 - マップの基本的な操作

Go言語で提供される map について基本的な操作を試してみます。

以下map生成のサンプル以外は基本的に package, import 部分の記述は省略しています


mapの生成

makeで生成

make関数を使って make(map[<キーの型>]<値の型>) を実行することで mapを生成することができます

■サンプルコード

package main

import "fmt"

func main() {
    m := make(map[string]int)

    fmt.Println(m)

    m["key1"] = 10
    m["key2"] = 20

    fmt.Println(m)
}

■実行結果

map[]
map[key1:10 key2:20]


マップリテラルで生成

map[<キーの型>]<値の型>{<キー>: <値>, <キー>: <値>, ...} で初期値をセットしたmapを作ることができます

package main

import "fmt"

func main() {
    m := map[string]int{
        "key1": 10,
        "key2": 20,
        "key3": 300,
        "key4": 400,
    }

    fmt.Println(m)
}

■実行結果

map[key3:300 key4:400 key1:10 key2:20]


値の取得

マップ[<キー>] でmapから対応する値を取得できます

■サンプルコード

func main() {
    m := map[string]int{
        "key1": 10,
        "key2": 20,
        "key3": 300,
        "key4": 400,
    }

    fmt.Println(m)

    // mapから値を取得
    fmt.Println(m["key2"])
    fmt.Println(m["key3"])
    fmt.Println(m["key99"])
}

■実行結果

マップ内に存在しないキーを使って、マップから値を取得しようとするとマップのエントリの型のゼロ値が返されます。
今回のサンプルでは “key99"(という存在しないキー)に対して 0 という値が返ってきています。

map[key2:20 key3:300 key4:400 key1:10]
20
300
0


値の存在チェック

マップ内に指定のキーに対する値が存在しているかは、戻り値を2つ受けて、2番目の戻り値で判断することができます。
val, ok = m[key]のような記述をして、「カンマok」慣用句と呼ばれるようです。
値が存在するなら ok はtrueとなり、そうでなければfalseとなります。

■サンプルコード

func main() {
    m := map[string]int{
        "key1": 10,
        "key2": 20,
        "key3": 300,
        "key4": 400,
    }

    value, ok := m["key2"]
    fmt.Printf("key2 -> exists=%t, value=%d\n", ok, value)

    value, ok = m["key99"]
    fmt.Printf("key99 -> exists=%t, value=%d\n", ok, value)

        // 値が存在するなら処理を行う
    if val, ok := m["key1"]; ok {
        fmt.Printf("key1 exists. value = %d\n", val)
    }
}

■実行結果

key2 -> exists=true, value=20
key99 -> exists=false, value=0
key1 exists. value = 10


値のセット

マップ[<キー>]=<値> で値をセットできます。エントリの新規追加も既存エントリの上書きのいずれもこの構文になります

■サンプルコード

func main() {
    m := map[string]int{
        "key1": 10,
        "key2": 20,
        "key3": 300,
        "key4": 400,
    }

    fmt.Println(m)

    m["key5"] = 500   // 新規追加
    m["key1"] = 10000 // 上書き

    fmt.Println(m)
}

■実行結果

map[key1:10 key2:20 key3:300 key4:400]
map[key1:10000 key2:20 key3:300 key4:400 key5:500]


エントリの削除

■サンプルコード

delete関数を用いて delete(<マップ>, <キー>)で対象のエントリを削除することができます

func main() {
    m := map[string]int{
        "key1": 10,
        "key2": 20,
        "key3": 300,
        "key4": 400,
    }

    fmt.Println(m)

    // 要素の削除
    delete(m, "key4")
    delete(m, "key99")

    fmt.Println(m)
}

■実行結果

map[key3:300 key4:400 key1:10 key2:20]
map[key1:10 key2:20 key3:300]


全エントリにアクセス

rangeを使用して、 for key, value := range マップ { <処理> } と記述することでマップ内の全エントリにアクセスして処理を行うことができます

■サンプルコード

func main() {
    m := map[string]int{
        "key1": 10,
        "key2": 20,
        "key3": 300,
        "key4": 400,
    }

    // 全エントリにアクセスして処理を実行
    for key, value := range m {
        fmt.Printf("key:%s -> value=%d\n", key, value)
    }
}

■実行結果

key:key4 -> value=400
key:key1 -> value=10
key:key2 -> value=20
key:key3 -> value=300


マップの要素数

マップに登録された要素の数を取得するにはlen関数を利用して、len(マップ)を実行することで取得できます

■サンプルコード

func main() {
    m := map[string]int{
        "key1": 10,
        "key2": 20,
        "key3": 300,
        "key4": 400,
    }

    fmt.Printf("element count: %d\n", len(m))
}

■実行結果

element count: 4