2014-04-24 44 views
2

有沒有寫在旅途中通用陣列/片重複數據刪除的方式,爲[]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{}把一切從[]int進去,把它傳遞給函數,然後把它放回[]interface{}並通過這個新的陣列,並把所有東西放在一個新的[]int

我的問題是,有沒有更好的方法來做到這一點?

+0

並非Go中的所有類型都支持相等性,所以它不能用於任何類型的切片。 – newacct

回答

3

雖然VonC的答案很可能不最接近你真正想要的,唯一真正的辦法做到這一點在本機進入無根是定義一個接口

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的功能。

這只是一個可能的例子,可能有更好的例子,但通常將每個元素映射到唯一的「==能夠」的ID,並且基於ID的重複數據刪除來構建新的列表或剔除可能是最直觀的方式。

另一種解決方案是取[]IDer,其中IDer接口只是ID() int。但是,這意味着用戶代碼必須創建[] IDer列表並將所有元素複製到該列表中,這有點難看。用戶將清單作爲ID列表而不是複製清理乾淨,但這種工作方式也是相似的。

+1

+1。這似乎是一個比我的答案提出的更原始的方式。 – VonC

2

我見過的唯一方法,在圍棋中實現與clipperhouse/gen項目,

根是企圖把一些仿製藥一樣的功能去的,從C#的LINQ和JavaScript的強調圖書館的一些啓示

this test

// Distinct returns a new Thing1s slice whose elements are unique. See: http://clipperhouse.github.io/gen/#Distinct 
func (rcv Thing1s) Distinct() (result Thing1s) { 
    appended := make(map[Thing1]bool) 
    for _, v := range rcv { 
     if !appended[v] { 
      result = append(result, v) 
      appended[v] = true 
     } 
    } 
    return result 
} 

,如clipperhouse.github.io/gen/解釋說:

爲您類型生成代碼,在開發時,使用命令行。

gen不是進口;生成的源代碼將成爲您的項目的一部分,並且不會受到外部依賴關係的影響。

1

你可以通過一個界面做一些事情。定義一個接口,比如稱爲「DeDupable」,需要一個func,比如UniqId()[]字節,然後你可以使用它來去除dups。和你的uniq的FUNC將採取[] DeDupable並在其上工作

+1

你介意如何將它同時應用於不同類型的切片,比如[] int和[]字符串嗎? – Ali

+0

http://play.golang.org/p/J6VWgI0adz – Apokalyptik

相關問題