2016-04-30 6 views
4

Juliaで複合タイプのSetを使用している場合、push!関数は重複した項目をセットに追加するようです。 Julia標準のドキュメントを読んで、私はisequal関数が重複をテストするために使われると仮定しました。私は誤解していると思うので、おそらく誰かが私を助けることができます。なぜpush!()はセットに重複要素を追加しますか?

例として、以下のコードを参照してください。特にt1と同じであるにもかかわらず、t2がセットに追加された理由を知りたいと思います。

ご協力いただきありがとうございます。注:私の場合、フィールドx1x2が等しい場合、タイプtの2つの変数は同一と見なされます。残りのフィールドの値は関係ありません。

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-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'を定義することはできません。 –

関連する問題