2016-04-30 30 views
4

在Julia中使用複合類型的Set時,push!函數似乎將重複項添加到該集合中。閱讀Julia標準文檔,我認爲isequal函數將用於測試重複項。我想我誤解了,所以也許有人可以幫助我。爲什麼push!()會將重複元素添加到Set?

舉個例子,看下面的代碼。特別是,我想知道爲什麼t2被添加到該設置,儘管與t1相同。

任何幫助,非常感謝。注意:在我的情況下,如果x1x2的字段相同,則認爲t類型的兩個變量是相同的;剩餘字段的值不重要。

type t 

    x1::Float64 
    x2::Float64 

    b1::Bool 
    b2::Bool 

end 

isequal(tx::t, ty::t) = (tx.x1 == ty.x1) && (tx.x2 == ty.x2) 
==(tx::t, ty::t)  = (tx.x1 == ty.x1) && (tx.x2 == ty.x2) 

t1 = t(1, 2, true, true) 
t2 = t(1, 2, true, true) 
tc = t1 
tdc = deepcopy(t1) 

[ t1 == t2 isequal(t1, t2)] # ---> [ true true ] 
[ t1 == tc isequal(t1, tc)] # ---> [ true true ] 
[ t1 == tdc isequal(t1, tdc)] # ---> [ true true ] 


s = Set{t}() 
push!(s, t1) 
push!(s, t2) # adds t2 to the set although t2 and t1 are identical ... 
push!(s, tc) # does not add ... 
push!(s, tdc) # adds tdc although tdc and t1 are identical 
+1

是否說明[這裏](http://stackoverflow.com/questions/34936593/overload-object-comparison-when-adding-to-a-set-in-julia)關於哈希回答你的問題? – DSM

+0

謝謝你指點我的討論。 – InkPen

回答

7

由於DSM所指出的,你只需要添加一個方法爲hash你的類型,即:

hash(x::t, h) = hash(x.x2, hash(x.x1, h)) 
+0

非常感謝您的幫助。我實際上遵循了Andrew Cooke的AutoHashEquals包提供的示例。 (https://github.com/andrewcooke/AutoHashEquals.jl) – InkPen

+0

這是一個很好的包,它提到了這個問題,如果你的類型不是不可變的,也就是說,如果你改變一個'Dict'中的對象,它會丟失(和'Set'在Julia中作爲'Dict'實現)。這是你的問題,還是你可以讓你的類型不可變?另外,它似乎沒有讓你只在字段的一個子集上定義'=='和'hash'。 –

相關問題