-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
Copy pathset.jl
111 lines (92 loc) · 2.46 KB
/
set.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
type Set{T}
dict::Dict{T,Nothing}
Set() = new(Dict{T,Nothing}())
Set(x...) = union!(new(Dict{T,Nothing}()), x)
end
Set() = Set{Any}()
Set(x...) = Set{Any}(x...)
Set{T}(x::T...) = Set{T}(x...)
show(io::IO, s::Set) = (show(io, typeof(s)); show_comma_array(io, s,'(',')'))
isempty(s::Set) = isempty(s.dict)
length(s::Set) = length(s.dict)
eltype{T}(s::Set{T}) = T
in(x, s::Set) = haskey(s.dict, x)
push!(s::Set, x) = (s.dict[x] = nothing; s)
pop!(s::Set, x) = (pop!(s.dict, x); x)
pop!(s::Set, x, deflt) = pop!(s.dict, x, deflt) == deflt ? deflt : x
delete!(s::Set, x) = (delete!(s.dict, x); s)
union!(s::Set, xs) = (for x=xs; push!(s,x); end; s)
setdiff!(s::Set, xs) = (for x=xs; delete!(s,x); end; s)
similar{T}(s::Set{T}) = Set{T}()
copy(s::Set) = union!(similar(s), s)
empty!{T}(s::Set{T}) = (empty!(s.dict); s)
start(s::Set) = start(s.dict)
done(s::Set, state) = done(s.dict, state)
# NOTE: manually optimized to take advantage of Dict representation
next(s::Set, i) = (s.dict.keys[i], skip_deleted(s.dict,i+1))
# TODO: simplify me?
pop!(s::Set) = (val = s.dict.keys[start(s.dict)]; delete!(s.dict, val); val)
join_eltype() = None
join_eltype(v1, vs...) = typejoin(eltype(v1), join_eltype(vs...))
union() = Set()
union(s::Set) = copy(s)
function union(s::Set, sets::Set...)
u = Set{join_eltype(s, sets...)}()
union!(u,s)
for t in sets
union!(u,t)
end
return u
end
intersect(s::Set) = copy(s)
function intersect(s::Set, sets::Set...)
i = copy(s)
for x in s
for t in sets
if !in(x,t)
delete!(i,x)
break
end
end
end
return i
end
function setdiff(a::Set, b::Set)
d = copy(a)
for x in b
delete!(d, x)
end
d
end
isequal(l::Set, r::Set) = (length(l) == length(r)) && (l <= r)
isless(l::Set, r::Set) = (length(l) < length(r)) && (l <= r)
<=(l::Set, r::Set) = issubset(l, r)
function issubset(l, r)
for elt in l
if !in(elt, r)
return false
end
end
return true
end
function unique(C)
out = Array(eltype(C),0)
seen = Set{eltype(C)}()
for x in C
if !in(x, seen)
push!(seen, x)
push!(out, x)
end
end
out
end
function filter!(f::Function, s::Set)
for x in s
if !f(x)
delete!(s, x)
end
end
return s
end
filter(f::Function, s::Set) = filter!(f, copy(s))
hash(s::Set) = hash(sort(s.dict.keys[s.dict.slots .!= 0]))