Golang中如何移除切片的切片中的重复元素?
Go语言中切片的切片去重方案
因为Go里切片是引用类型,不可哈希,不能直接作为map的键,所以要换个思路——把每个子切片转换成可哈希的类型作为map的键,以此来跟踪重复项。下面是两种实用的实现方式:
方法1:将子切片转为带分隔符的字符串
把每个子切片的元素拼接成带分隔符的字符串(比如逗号),用这个字符串作为map的键。这种方法适用于子切片长度不固定的场景。
package main import ( "fmt" "strconv" "strings" ) func main() { input := [][]int{{-1, -1, 2}, {-1, 0, 1}, {-1, 0, 1}} seen := make(map[string]bool) var unique [][]int for _, subSlice := range input { // 将子切片元素转为字符串并拼接 var parts []string for _, num := range subSlice { parts = append(parts, strconv.Itoa(num)) } key := strings.Join(parts, ",") if !seen[key] { seen[key] = true // 复制子切片到新切片,避免引用原底层数组 unique = append(unique, append([]int(nil), subSlice...)) } } fmt.Println(unique) // 输出: [[-1 -1 2] [-1 0 1]] }
注意:要选择不会和元素内容冲突的分隔符,比如如果元素包含逗号,就换用其他符号(如|),避免不同子切片生成相同的键。
方法2:将子切片转为固定长度的数组
如果所有子切片的长度固定(比如你的例子里都是3个int),可以直接把子切片转换成对应长度的数组——数组是值类型,可哈希,能直接作为map的键,效率比字符串方法更高。
package main import "fmt" func main() { input := [][]int{{-1, -1, 2}, {-1, 0, 1}, {-1, 0, 1}} seen := make(map[[3]int]bool) var unique [][]int for _, subSlice := range input { // 转换为固定长度的数组作为键 key := [3]int{subSlice[0], subSlice[1], subSlice[2]} if !seen[key] { seen[key] = true unique = append(unique, append([]int(nil), subSlice...)) } } fmt.Println(unique) // 输出: [[-1 -1 2] [-1 0 1]] }
关键注意点
无论用哪种方法,都要通过append([]int(nil), subSlice...)创建新的切片加入结果,而不是直接添加原subSlice。这是因为切片是引用类型,如果直接添加原切片,后续原切片的修改会影响结果切片中的元素。
内容的提问来源于stack exchange,提问作者chetan honnavile
相关产品推荐
相关产品推荐

