-
Notifications
You must be signed in to change notification settings - Fork 0
/
orddict.jl
117 lines (96 loc) · 2.4 KB
/
orddict.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
112
113
114
115
116
117
import Base: getindex, setindex!, get, delete!,
length, iterate,
getproperty, setproperty!,
haskey, isempty,
union,
copy, push!
mutable struct OrdDict <: AbstractDict{Symbol,String}
items::Vector{Pair{Symbol, String}}
end
OrdDict() = OrdDict(Pair{Symbol, String}[])
OrdDict(items...) = OrdDict(collect(items))
# iteration definitions
length(a::OrdDict) = length(a.items)
isempty(a::OrdDict) = isempty(a.items)
iterate(a::OrdDict) = iterate(a.items)
iterate(a::OrdDict, i) = iterate(a.items, i)
# getindex needed for dictionary-like key lookup
function getindex(a::OrdDict, key::Symbol)
for item in a.items
if first(item) == key
return last(item)
end
end
throw(KeyError(key))
end
# alternative multiple dispatch implementation by number
getindex(a::OrdDict, index::Integer) = a.items[index]
function setindex!(a::OrdDict, value::AbstractString, key::Symbol)
for (i, item) in enumerate(a.items)
if first(item) == key
a.items[i] = key => value
return
end
end
push!(a.items, key => value)
end
push!(a::OrdDict, x::Pair{Symbol, String}) = push!(a.items, x)
function haskey(a::OrdDict, key::Symbol)
for item in a.items
if first(item) == key
return true
end
end
false
end
function delete!(a::OrdDict, key::Symbol)
for (i, item) in enumerate(a.items)
if first(item) == key
deleteat!(a.items, i)
end
end
a
end
# make it act like a dictionary
# need to keep the OrdDict.items to behave as usual
function getproperty(a::OrdDict, key::Symbol)
if key == :items
getfield(a, :items)
else
a[key]
end
end
function setproperty!(a::OrdDict, key::Symbol, value::String)
if key == :items
setfield!(a, :item, value)
else
a[key] = value
end
end
# julia> d = OrdDict(:one => "1", :two => "2")
# OrdDict with 2 entries:
# :one => "1"
# :two => "2"
# julia> d.one
# "1"
# julia> d.items
# 2-element Vector{Pair{Symbol, String}}:
# :one => "1"
# :two => "2"
# julia> d.two
# "2"
# julia> d.three = "3"
# "3"
# julia> d.three
# "3"
# julia> d.items
# 3-element Vector{Pair{Symbol, String}}:
# :one => "1"
# :two => "2"
# :three => "3"
# julia> for (k,v) in d
# println("key: ", k, " value: ", v)
# end
# key: one value: 1
# key: two value: 2
# key: three value: 3