2016-04-30 31 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'。 –

相关问题