为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕田峪4524236 2022-07-18 16:23:45
假设输入可以包含字符串或整数值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)}这仅在输入是字符串或整数但不是两者时才有效 如何确保此函数适用于数组接口
查看完整描述

3 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

使用反射包编写一个适用于任何切片类型的函数:


func unique(src interface{}) interface{} {

    srcv := reflect.ValueOf(src)

    dstv := reflect.MakeSlice(srcv.Type(), 0, 0)

    visited := make(map[interface{}]struct{})

    for i := 0; i < srcv.Len(); i++ {

        elemv := srcv.Index(i)

        if _, ok := visited[elemv.Interface()]; ok {

            continue

        }

        visited[elemv.Interface()] = struct{}{}

        dstv = reflect.Append(dstv, elemv)

    }

    return dstv.Interface()

}

像这样使用它:


uniqueIntSlice := unique(intSlice).([]int)

在 Go Playground 上运行代码。


查看完整回答
反对 回复 2022-07-18
?
四季花海

TA贡献1811条经验 获得超5个赞

如何确保此函数适用于(未排序的)空接口切片{}

考虑到空接口{}具有可比性(https://stackoverflow.com/a/54003329/4466350)


因此,要回答您的问题,重写原始代码非常简单


package main


import (

    "fmt"

)


func main() {

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

    fmt.Println(unique(intSlice))

}


func unique(src []interface{}) []interface{} {

    keys := make(map[interface{}]bool)

    list := []interface{}{}

    for _, entry := range src {

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

            keys[entry] = true

            list = append(list, entry)

        }

    }

    return list

}

https://play.golang.org/p/vW7vgwz9yc1


如果您的问题变成,如何删除任何切片类型的重复项,请查看其他答案https://stackoverflow.com/a/65191679/4466350


查看完整回答
反对 回复 2022-07-18
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

没有什么优雅而且很容易出错,但是您可以使用一个接收两个interface{}参数的函数,第一个是要过滤的切片,第二个是指向过滤切片的指针,显然如果第一个参数是 int 切片,则第二个必须是指向 int 切片的指针。


在函数内部,您可以检查参数的类型并分别处理它们。


package main


import (

    "fmt"

)


func unique(slice interface{}, filtered interface{}) error {


    // Check for slice of string

    if sliceOfString, ok := slice.([]string); ok {


        // If slice is slice of string filtered MUST also be slice of string

        filteredAsSliceOfString, ok := filtered.(*[]string)

        if  !ok {

            return fmt.Errorf("filtered should be of type %T, got %T instead", &[]string{}, filtered)

        }


        keys := make(map[string]bool)


        for _, entry := range sliceOfString {

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

                keys[entry] = true

                *filteredAsSliceOfString = append(*filteredAsSliceOfString, entry)

            }

        }


    }else if sliceOfInt, ok := slice.([]int); ok {


        // If slice is slice of int filtered MUST also be slice of int

        filteredAsInt, ok := filtered.(*[]int)

        if !ok {

            return fmt.Errorf("filtered should be of type %T, got %T instead", &[]string{}, filtered)

        }


        keys := make(map[int]bool)


        for _, entry := range sliceOfInt {

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

                keys[entry] = true

                *filteredAsInt = append(*filteredAsInt, entry)

            }

        }


    } else {

        return fmt.Errorf("only slice of in or slice of string is supported")

    }


    return nil


}


func main() {

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

    intSliceFiltered := make([]int, 0)

    stringSlice := []string{"a", "b", "b", "c", "c", "c", "d"}

    stringSliceFiltered := make([]string, 0)


    fmt.Println(intSlice)

    err := unique(intSlice, &intSliceFiltered) // Very important to send pointer in second parameter

    if err != nil {

        fmt.Printf("error filtering int slice: %v\n", err)

    }

    fmt.Println(intSliceFiltered)


    fmt.Println(stringSlice)

    err = unique(stringSlice, &stringSliceFiltered) // Very important to send pointer in second parameter

    if err != nil {

        fmt.Printf("error filtering string slice: %v\n", err)

    }

    fmt.Println(stringSliceFiltered)

}

正如我所说,它并不优雅。我没有检查这个是否有错误。


它在这里运行。


查看完整回答
反对 回复 2022-07-18
  • 3 回答
  • 0 关注
  • 164 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号