はじめに
Go言語の標準に、PHPでいうところの、array_unique
みたいな関数が見当たらず、関数にしてみたので共有します。
とはいえ、定番のmap式の重複処理を関数にしただけですが…笑
初学者向けにしっかりめに解説してますので、ツッコミあれば、ぜひコメント欄に書いて頂けると嬉しいです!
今日のコード
サクッと動作確認コーナー
- 下の実行ボタンを押せば、動作確認ができます。
- コードを書き換えて実行することもできます。
- コードを元に戻したい場合は、この記事をリロードして下さい。
コード全文
package main
import "fmt"
func main(){
target := []string{"あ", "い", "う", "あ"}
unique := sliceUnique(target)
fmt.Println(unique) // -> [あ い う]
}
func sliceUnique(target []string) (unique []string) {
m := map[string]bool{}
for _, v := range target {
if !m[v] {
m[v] = true
unique = append(unique, v)
}
}
return unique
}
関数部分のコード
func SliceUnique(target []string) (unique []string) {
m := map[string]bool{}
for _, v := range target {
if !m[v] {
m[v] = true
unique = append(unique, v)
}
}
return unique
}
先ほどの全文の下半分です。
関数部分をざっくり解説
解説の前に
この関数は、
- マップのキー名は重複されない
- boolの初期値はfalse
という言語仕様を利用しています。
それでは、引数に使っていた[]string{"あ", "い", "う", "あ"}
を使って、詳しく解説していきます。
for文 1週目
m["あ"] = false
まず、targetがfor文に入り、if文に入ってきたとき、m["あ"]
が生成され、同時に初期値としてfalseが設定されます。
m["あ"] = true
targetがif文の中に入り1行目。
このとき、m["あ"] = true
とされていることに注目しておいて下さい。
unique = append(unique, "あ")
targetがif文の中に入り2行目。
append関数によって、"あ"
が空のSliceunique
に追加されています。
for文 2週目〜3週目
基本的には1周目と同じような処理となります。
周ごとに、m["い"] = true
、m["う"] = true
が生成され、
unique
スライスはunique = []string{"あ", "い", "う"}
と追加されていきます。
for文4周目
さて、問題の重複している値「あ」
が入ってくる4周目です。
if m["あ"] == false
関数内ではif !m[v]
と書かれていますが、これはif m[v] == false
と同じ意味です。
また、1周目ですでにm["あ"]
が生成されており、m["あ"] = true
と代入されています。
これにより、4周目だけこのif文内がスキップされ、unique
スライスにも追加されることなく、4周目を終えます。
解説の締め
重複した要素が何周目に来ても、今回の4周目のように処理されます。
こうして、重複した要素が除外されます。
さいごに
くどいぐらい説明してますが、最後まで読んで頂いて、ありがとうございます。
何かツッコミあれば、TwitterのDMにてお待ちしております。
ツッコミに揉まれて良い記事になれば、嬉しいです。