Hi,
I have a set filled with custom objects.
How can I get a specific item from the set equal to another object?
For example, I have a set of points. Then, I add a new point pp1. If pp1 already exists in the set, I want a way to obtain the stored object. This is because the stored point is the one required and may have references elsewhere.
mutable struct Pt
x::Float64
y::Float64
end
Base.hash(p::Pt) = hash((p.x+p.y,))
Base.:(==)(p1::Pt, p2::Pt) = hash(p1)==hash(p2)
p1 = Pt(1,0)
p2 = Pt(2,0)
S = OrderedSet([p1, p2])
# a new point
pp1 = Pt(1,0)
# Since pp1 is equal to p1, how to get p1 from the set?
I got a solution for OrderedSets as follows, but I might be missing some standard procedure to do that.
using DataStructures
mutable struct Pt
x::Float64
y::Float64
end
Base.hash(p::Pt) = hash((p.x+p.y,))
Base.:(==)(p1::Pt, p2::Pt) = hash(p1)==hash(p2)
# function to get an item from a Set (based on the ht_keyindex function from DataStructures
function getitem(s::OrderedSet{K}, key) where K
h = s.dict
slots = h.slots
sz = length(slots)
iter = 0
maxprobe = h.maxprobe
index = Base.hashindex(key, sz)
keys = h.keys
@inbounds while iter <= maxprobe
si = slots[index]
si==0 && break # slot empty
if si>0 && isequal(key, keys[si])
return keys[si] # it returns the key instead of the index
end
index = (index & (sz-1)) + 1
iter += 1
end
error("key not found")
end
p1 = Pt(1,0)
p2 = Pt(2,0)
S = OrderedSet([p1, p2])
# the objectid obtained from getitem(S,pp1) is the one from p1 (as desired)
@show objectid( getitem(S,pp1) ) == objectid(p1)