我们可以写一个通用的数组/重复数据删除吗? [英] Can we write a generic array/slice deduplication in go?

查看:132
本文介绍了我们可以写一个通用的数组/重复数据删除吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在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 :=范围列表{
unique_set [x] = true
}
result:= make([] int,len(unique_set))
i:= 0
x:= range unique_set {
result [i] = x
i ++
}
返回结果
}
pre>

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

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

我知道你可以用该签名写这个函数,但是实际上你不能在 [] int ,您需要创建一个 [] interface {} 将所有内容从 [] int ,将其传递给函数,然后将其返回并将其放入 [] interface {} 中,并通过此新数组将所有内容放入一个新的 [] int



我的问题是是否有更好的方法?

解决方案

虽然VonC的答案可能与您真正想要的最接近,是定义一个界面

  type IDList interface {
//返回i $ b $上的元素的id b ID(i int)int

//返回元素
//给定的id
GetByID(id int)interface {}

Len()int

//将元素添加到列表
Insert(interface {})
}

//将重复数据删除的列表放入dst
func重复数据删除(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的功能。



这是jus一个可能的例子,可能有更好的例子,但是通常将每个元素映射到唯一的== ableID,并且基于ID的重复数据删除构建新的列表或剔除可能是最直观的方式。



另一个解决方案是收取 [] IDer ,其中 IDer interface只是 ID()int 。然而,这意味着用户代码必须创建[] IDer列表,并将所有元素复制到该列表中,这是一个有点丑陋。用户将列表替换为ID列表而不是复制更简洁,但这两种方式的工作量相似。


Is there a way to write a generic array/slice deduplication in go, for []int we can have something like (from 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
}

But is there a way to extend it to support any array? with a signature like:

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

I know that you can write that function with that signature, but then you can't actually use it on []int, you need to create a []interface{} put everything from the []int into it, pass it to the function then get it back and put it into a []interface{} and go through this new array and put everything in a new []int.

My question is, is there a better way to do this?

解决方案

While VonC's answer probably does the closest to what you really want, the only real way to do it in native Go without gen is to define an interface

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))
    }
}

Where uniq is the function from your OP.

This is just one possible example, and there are probably much better ones, but in general mapping each element to a unique "==able" ID and either constructing a new list or culling based on the deduplication of the IDs is probably the most intuitive way.

An alternate solution is to take in an []IDer where the IDer interface is just ID() int. However, that means that user code has to create the []IDer list and copy all the elements into that list, which is a bit ugly. It's cleaner for the user to wrap the list as an ID list rather than copy, but it's a similar amount of work either way.

这篇关于我们可以写一个通用的数组/重复数据删除吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆