Go の slice で、重複をする項目を除外したい時があり、その実装をしたので方法を書き留めます。
int 型のスライスで重複している値を削除する
map を用いて重複の削除を行います。
map の key に slice の値を設定し、value に bool を設定します。
同じ key の場合は上書きで値が更新されるため、一度 true を設定することで、それ以後重複を除いた新たな slice に追加しなければ、重複除外が可能です。
package main
import "fmt"
func deleteDuplicate(slice []int64) []int64 {
uniqueCheck := make(map[int64]bool)
newSlice := []int64{}
for _, i := range slice {
// 重複している場合uniqueCheck[i]の値はtrueのためスキップされる
if !uniqueCheck[i] {
uniqueCheck[i] = true
// 1度目のkey設定のときのみ重複除外用のsliceに追加する
newSlice = append(newSlice, i)
}
}
return newSlice
}
func main() {
slice := []int64{1, 3, 5, 7, 7, 2, 3, 9, 6, 5, 9, 10, 1000, 3, 8}
fmt.Printf("%+v", deleteDuplicate(slice)) // [1 3 5 7 2 9 6 10 1000 8]
}
bool の代わりに空の構造体を使用する
bool 値の代わりに、空の構造体 struct{}を使用すると、余分なメモリを確保せずに実装が可能です。
package main
import "fmt"
func deleteDuplicate(slice []int64) []int64 {
uniqueCheck := make(map[int64]struct{})
newSlice := []int64{}
for _, i := range slice {
// uniqueChec[i]でmap内でkey(i)の存在チェックを行う
if _, exists := uniqueCheck[i]; !exists {
uniqueCheck[i] = struct{}{}
newSlice = append(newSlice, i)
}
}
return newSlice
}
func main() {
slice := []int64{1, 3, 5, 7, 7, 2, 3, 9, 6, 5, 9, 10, 1000, 3, 8}
fmt.Printf("%+v", deleteDuplicate(slice)) // [1 3 5 7 2 9 6 10 1000 8]
}