[Go] sliceの重複処理を行う、array_unique関数みたいなものを作ってみた (解説付)

はじめに

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["い"] = truem["う"] = 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にてお待ちしております。
ツッコミに揉まれて良い記事になれば、嬉しいです。

参考

PON3

PON3

5年くらい前に、30代完全未経験から独学でWeb系のソフトウェアエンジニアになった人。 現在はフリーランスエンジニアとして、大阪の自宅からフルリモートで東京の自社開発企業のお仕事をしている。 主戦場はバックエンドで、Go言語でのAPI開発や、Pythonでのデータ分析が武器。 とは言いつつ、フロントエンドをSPAを実装したり、IaCでクラウドインフラの設計構築したり、スクラム開発でプロジェクト運営したりするなんでも屋。 いつも、ググってきては誰かが書いてくれた記事を見て開発していたが、もらってばかりでなく世の中に返すこともしたいと思い、技術ブログをはじめる。 妻と2歳になる娘の3人暮らし。 何かご用件がある方は、TwitterのDMからどうぞ。