LoginSignup
0
0

GoでKeyとValueを逆にしたMapを作成する

Last updated at Posted at 2023-10-29

goでMapを定義したときに
そのkeyとvalueを逆にする方法を紹介します。

例えば、以下のようにprotoで定義された型からアプリケーション上で定義したmodelに
マッピングするために、Mapを用いることがあるかと思うのですが、
proto->modelのMapからmodel->protoのMapを生成する方法を紹介します。

具体的には次のようなケースを想定しています。

// 以下のようなMapから
var protpToModelMap = map[v1.PaymentMethod]paymentmethod.PaymentMethod{
	v1.Credit:      paymentmethod.Credit,
    v1.PayPay:      paymentmethod.PayPay,
	v1.AuPay:       paymentmethod.AuPay,
	v1.RakutenPay:  paymentmethod.RakutenPay,

}

// 次のようなMapを作成したい時
var modelToProtoMap = map[paymentmethod.PaymentMethod]v1.PaymentMethod{
	paymentmethod.Credit:     v1.Credit,
    paymentmethod.PayPay:     v1.PayPay,
	paymentmethod.AuPay:      v1.AuPay,
	paymentmethod.RakutenPay: v1.RakutenPay,

}

次のような関数でKeyとValueを逆にしたMapを作成できます。

// ReverseMap keyとValueを入れ替えたMapを作成する
func ReverseMap[T, S ~string | ~int](m map[T]S) map[S]T {
	n := make(map[S]T, len(m))
	for k, v := range m {
        if existKey, ok := n[v]; ok {
            panic(fmt.Sprintf("重複したkeyが存在します key:%v",existKey))
		}
		n[v] = k
	}
	return n
}

var modelToProtoMap = ReverseMap(protpToModelMap)

補足

引数で受け取るMapのkeyとvalueのジェネリクスの型に
~がついているのは Underlying Type と呼ばれているもので
基礎となる型がintである型を要求していることを意味しています。
この~がないとgoのenumを使うときに定義される独自タイプ(例:type PaymentMethod int)を引数として渡すことができなくなってしまいます。

参考:https://zenn.dev/waawaa/articles/ac07cf53a69cccca156c

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0