如何删除接口数组中的重复项

假设输入可以包含字符串或整数值


names = ["rahul", "rohit","srujan", "rahul"] --> output = ["rahul", "rohit","srujan"] 

 age=[12,18,12,21] --> output = [12,18,21]

我们可以利用这个功能来过滤重复


package main

  

import (

"fmt"

)

  

func unique(intSlice []int) []int {

    keys := make(map[int]bool)

    list := []int{} 

    for _, entry := range intSlice {

        if _, value := keys[entry]; !value {

            keys[entry] = true

            list = append(list, entry)

        }

    }    

    return list

}

  

func main() {

    intSlice := []int{1,5,3,6,9,9,4,2,3,1,5}

    fmt.Println(intSlice) 

    uniqueSlice := unique(intSlice)

    fmt.Println(uniqueSlice)

}

这仅在输入是字符串或整数但不是两者时才有效 如何确保此函数适用于数组接口


慕田峪4524236
浏览 165回答 3
3回答

跃然一笑

使用反射包编写一个适用于任何切片类型的函数:func unique(src interface{}) interface{} {&nbsp; &nbsp; srcv := reflect.ValueOf(src)&nbsp; &nbsp; dstv := reflect.MakeSlice(srcv.Type(), 0, 0)&nbsp; &nbsp; visited := make(map[interface{}]struct{})&nbsp; &nbsp; for i := 0; i < srcv.Len(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; elemv := srcv.Index(i)&nbsp; &nbsp; &nbsp; &nbsp; if _, ok := visited[elemv.Interface()]; ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; visited[elemv.Interface()] = struct{}{}&nbsp; &nbsp; &nbsp; &nbsp; dstv = reflect.Append(dstv, elemv)&nbsp; &nbsp; }&nbsp; &nbsp; return dstv.Interface()}像这样使用它:uniqueIntSlice := unique(intSlice).([]int)在 Go Playground 上运行代码。

四季花海

如何确保此函数适用于(未排序的)空接口切片{}考虑到空接口{}具有可比性(https://stackoverflow.com/a/54003329/4466350)因此,要回答您的问题,重写原始代码非常简单package mainimport (&nbsp; &nbsp; "fmt")func main() {&nbsp; &nbsp; intSlice := []interface{}{1, 5, 3, 6, 9, 9, 4, 2, 3, 1, 5}&nbsp; &nbsp; fmt.Println(unique(intSlice))}func unique(src []interface{}) []interface{} {&nbsp; &nbsp; keys := make(map[interface{}]bool)&nbsp; &nbsp; list := []interface{}{}&nbsp; &nbsp; for _, entry := range src {&nbsp; &nbsp; &nbsp; &nbsp; if _, value := keys[entry]; !value {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keys[entry] = true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list = append(list, entry)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return list}https://play.golang.org/p/vW7vgwz9yc1如果您的问题变成,如何删除任何切片类型的重复项,请查看其他答案https://stackoverflow.com/a/65191679/4466350

蓝山帝景

没有什么优雅而且很容易出错,但是您可以使用一个接收两个interface{}参数的函数,第一个是要过滤的切片,第二个是指向过滤切片的指针,显然如果第一个参数是 int 切片,则第二个必须是指向 int 切片的指针。在函数内部,您可以检查参数的类型并分别处理它们。package mainimport (&nbsp; &nbsp; "fmt")func unique(slice interface{}, filtered interface{}) error {&nbsp; &nbsp; // Check for slice of string&nbsp; &nbsp; if sliceOfString, ok := slice.([]string); ok {&nbsp; &nbsp; &nbsp; &nbsp; // If slice is slice of string filtered MUST also be slice of string&nbsp; &nbsp; &nbsp; &nbsp; filteredAsSliceOfString, ok := filtered.(*[]string)&nbsp; &nbsp; &nbsp; &nbsp; if&nbsp; !ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return fmt.Errorf("filtered should be of type %T, got %T instead", &[]string{}, filtered)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; keys := make(map[string]bool)&nbsp; &nbsp; &nbsp; &nbsp; for _, entry := range sliceOfString {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if _, value := keys[entry]; !value {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keys[entry] = true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *filteredAsSliceOfString = append(*filteredAsSliceOfString, entry)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }else if sliceOfInt, ok := slice.([]int); ok {&nbsp; &nbsp; &nbsp; &nbsp; // If slice is slice of int filtered MUST also be slice of int&nbsp; &nbsp; &nbsp; &nbsp; filteredAsInt, ok := filtered.(*[]int)&nbsp; &nbsp; &nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return fmt.Errorf("filtered should be of type %T, got %T instead", &[]string{}, filtered)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; keys := make(map[int]bool)&nbsp; &nbsp; &nbsp; &nbsp; for _, entry := range sliceOfInt {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if _, value := keys[entry]; !value {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keys[entry] = true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *filteredAsInt = append(*filteredAsInt, entry)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; return fmt.Errorf("only slice of in or slice of string is supported")&nbsp; &nbsp; }&nbsp; &nbsp; return nil}func main() {&nbsp; &nbsp; intSlice := []int{1,5,3,6,9,9,4,2,3,1,5}&nbsp; &nbsp; intSliceFiltered := make([]int, 0)&nbsp; &nbsp; stringSlice := []string{"a", "b", "b", "c", "c", "c", "d"}&nbsp; &nbsp; stringSliceFiltered := make([]string, 0)&nbsp; &nbsp; fmt.Println(intSlice)&nbsp; &nbsp; err := unique(intSlice, &intSliceFiltered) // Very important to send pointer in second parameter&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("error filtering int slice: %v\n", err)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println(intSliceFiltered)&nbsp; &nbsp; fmt.Println(stringSlice)&nbsp; &nbsp; err = unique(stringSlice, &stringSliceFiltered) // Very important to send pointer in second parameter&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("error filtering string slice: %v\n", err)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println(stringSliceFiltered)}正如我所说,它并不优雅。我没有检查这个是否有错误。它在这里运行。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go