亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何刪除接口數組中的重復項

如何刪除接口數組中的重復項

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 關注
  • 154 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號