一尘不染

我们可以在go中编写通用数组/切片重复数据删除吗?

go

有没有一种方法可以编写通用的数组/切片重复数据删除,因为[]int我们可以有一些类似的东西(来自http://rosettacode.org/wiki/Remove_duplicate_elements#Go):

func uniq(list []int) []int {
  unique_set := make(map[int] bool, len(list))
  for _, x := range list {
     unique_set[x] = true
   }
  result := make([]int, len(unique_set))
  i := 0
  for x := range unique_set {
     result[i] = x
    i++
  }
  return result
}

但是有没有办法扩展它以支持任何数组?签名如下:

func deduplicate(a []interface{}) []interface{}

我知道您可以使用该签名编写该函数,但是您实际上不能在上使用它[]int,您需要创建一个[]interface{}put命令,将所有内容都[]int放入其中,然后将其传递给函数,然后再将其放回a
[]interface{}和经历这个新的数组并将所有内容都放在一个新的[]int

我的问题是, 有更好的方法吗?


阅读 245

收藏
2020-07-02

共1个答案

一尘不染

尽管VonC的答案可能与您真正想要的最接近,但在没有gen的本机Go中实现此目的的唯一真实方法是定义一个接口

type IDList interface {
   // Returns the id of the element at i
   ID(i int) int

   // Returns the element
   // with the given id
   GetByID(id int) interface{}

   Len() int

   // Adds the element to the list
   Insert(interface{})
}

// Puts the deduplicated list in dst
func Deduplicate(dst, list IDList) {
    intList := make([]int, list.Len())
    for i := range intList {
        intList[i] = list.ID(i)
    }

    uniques := uniq(intList)
    for _,el := range uniques {
        dst.Insert(list.GetByID(el))
    }
}

uniq您的OP的功能在哪里。

这只是一个可能的示例,可能还有很多更好的示例,但是通常将每个元素映射到唯一的“ == able”
ID并基于ID的重复数据删除构建新列表或剔除可能是最直观的方式。

另一种解决方案是采用接口正好位于的[]IDer位置。但是,这意味着 用户* 代码必须创建[]
IDer列表并将所有元素复制到该列表中,这有点难看。对于用户而言,将列表包装为ID列表而不是副本是比较干净的方法,但这两种方法的工作量都差不多。IDer``ID() int
*

2020-07-02