🐀

【Go】スライスから重複を排除し、ユニークなスライスを作成する方法

2022/06/25に公開

表題の通りです。
slices.Compact()を利用します。

slices.Compact()の説明を見てみると以下のような記載があります。

Compact replaces consecutive runs of equal elements with a single copy. This is like the uniq command found on Unix. Compact modifies the contents of the slice s; it does not create a new slice. When Compact discards m elements in total, it might not modify the elements s[len(s)-m:len(s)]. If those elements contain pointers you might consider zeroing those elements so that objects they reference can be garbage collected.

隣り合う連続する等価な値をシングルコピーに置き換えるとのことなのでまずはslice.Sort()を実行してからslice.Compact()を実行します。

https://go.dev/play/p/SxKl1M9yKiW

// You can edit this code!
// Click here and start typing.
package main

import (
	"fmt"

	"golang.org/x/exp/slices"
)

func main() {
	strs := []string{"A", "B", "C", "A", "A", "D", "B", "E", "F"}
	slices.Sort(strs)
	unique := slices.Compact(strs)
	fmt.Printf("%+v\n", unique)
}

output
[A B C D E F]

Program exited.

mapを使う場合は以下のようにします。

https://go.dev/play/p/qlnIk31aI1x

// You can edit this code!
// Click here and start typing.
package main

import (
	"fmt"
)

func main() {
	strs := []string{"A", "B", "C", "A", "A", "D", "B", "E", "F"}
	var unique []string
	encounter := map[string]int{}
	for _, v := range strs {
		if _, ok := encounter[v]; !ok {
			encounter[v] = 1
			unique = append(unique, v)
		} else {
			encounter[v]++
		}
	}
	fmt.Printf("%+v\n", unique)
	fmt.Printf("%+v", encounter)
}
output
[A B C D E F]
map[A:3 B:2 C:1 D:1 E:1 F:1]
Program exited.

Discussion