
(資料圖片)
耐心和持久勝過激烈和狂熱。
哈嘍大家好,我是陳明勇,今天分享的內容是巧用 Go Map 特性對數組或切片進行去重。如果本文對你有幫助,不妨點個贊,如果你是 Go 語言初學者,不妨點個關注,一起成長一起進步,如果本文有錯誤的地方,歡迎指出!
在其他語言里(如 ??Java?
?? )使用過 ??Set?
?? 集合的小伙伴都知道,它的一個特點就是集合里的元素是不重復的。在一些需要去重場景中,我們可以使用 ??Set?
?? 這種數據結構去存儲數據,達到去重的目的。而在 ??Go?
?? 語言里面,是沒有 ??Set?
? 這種數據類型的。如果我們想利用無重復元素的數據結構對數組或切片去重,可以使用 ??Go?
?? 的復合數據類型 ??Map?
?? 去構建 ??Set?
?? 集合,對數組或切片進行去重。因為 ??Map?
?? 中的 ??key?
?? 是唯一的,如果不了解 ??Map?
?? 的小伙伴,可以看看我的這篇文章 ??一文了解 Go 的復合數據類型(數組、Slice 切片、Map)??。
type MySet map[any]struct{}
定義一個自定義類型 ??MySet?
?? ,具有 ??map[any]strcut{}?
? 的特性。
?map?
?? 的 ??key?
?? 是 ??any?
?? 類型,任何類型都可以當做 ??map?
?? 的 ??key?
?;??map?
?? 的 ??value?
?? 是 ??struct{}?
?? 類型,為什么會用結構體類型?是因為后面添加 ??k-v?
?? 鍵值對時,指定的 ??value?
?? 為 空結構體 ??strcut{}{}?
??,??fmt.Println(unsafe.Sizeof(struct{}{})) // 0?
? 空結構體是不占用內存空間的。import "fmt"type MySet map[any]struct{}func main() { s1 := []int{1, 1, 2, 3} fmt.Println(duplicateRemoving(s1)) // [1 2 3] s2 := []string{"a", "b", "c", "a"} fmt.Println(duplicateRemoving(s2)) // [a b c]}func duplicateRemoving[T any](s []T) []T { res := make([]T, 0, len(s)) mySet := make(MySet) for _, t := range s { if _, ok := mySet[t]; !ok { res = append(res, t) mySet[t] = struct{}{} } } return res}
核心思路
定義一個新的切片 ??res?
??,為去重后的切片;定義一個 ??MySet ?
?? 類型的變量 ??mySet?
?,用于判斷元素是否重復;遍歷原切片 ??s?
??,首先判斷 ??mySet?
?? 里是否存在以切片 ??s?
?? 的元素 ??t?
?? 為 ??key?
?? 的鍵值對,如果不存在,往新切片 ??res?
?? 添加元素 ??t?
??,往 ??mySet?
?? 里添加鍵值對 ??t → struct{}{}?
?,否則說明元素重復,不做添加操作;返回去重后的新切片。本文介紹了如何利用 ??Go?
?? 的復合數據類型 ??Map?
?? 的特性對數組或切片進行去重。值得注意的一個地方是,在使用 ??Map?
?? 構建 ??Set?
?? 時,??Value?
?? 的數據類型指定為 ??struct{}?
??,原因是后面在添加鍵值對的時候,指定的 ??Value?
?? 為空結構體 ??strcut{}{}?
?,空結構體不占用內存空間。